Add new BMCS: based on Jambu's code but migrated to 'gmcs' so we get generics support
authorMiguel de Icaza <miguel@gnome.org>
Tue, 11 Jan 2005 22:05:11 +0000 (22:05 -0000)
committerMiguel de Icaza <miguel@gnome.org>
Tue, 11 Jan 2005 22:05:11 +0000 (22:05 -0000)
svn path=/trunk/mcs/; revision=38735

48 files changed:
mcs/bmcs/AssemblyInfo.cs [new file with mode: 0644]
mcs/bmcs/ChangeLog [new file with mode: 0644]
mcs/bmcs/CryptoConvert.cs [new file with mode: 0644]
mcs/bmcs/Makefile [new file with mode: 0644]
mcs/bmcs/README [new file with mode: 0644]
mcs/bmcs/anonymous.cs [new file with mode: 0644]
mcs/bmcs/assign.cs [new file with mode: 0644]
mcs/bmcs/attribute.cs [new file with mode: 0644]
mcs/bmcs/bmcs.exe.config [new file with mode: 0644]
mcs/bmcs/bmcs.exe.sources [new file with mode: 0644]
mcs/bmcs/cfold.cs [new file with mode: 0644]
mcs/bmcs/class.cs [new file with mode: 0644]
mcs/bmcs/codegen.cs [new file with mode: 0644]
mcs/bmcs/const.cs [new file with mode: 0644]
mcs/bmcs/constant.cs [new file with mode: 0644]
mcs/bmcs/convert.cs [new file with mode: 0644]
mcs/bmcs/decl.cs [new file with mode: 0644]
mcs/bmcs/delegate.cs [new file with mode: 0644]
mcs/bmcs/doc.cs [new file with mode: 0644]
mcs/bmcs/driver.cs [new file with mode: 0644]
mcs/bmcs/ecore.cs [new file with mode: 0644]
mcs/bmcs/enum.cs [new file with mode: 0644]
mcs/bmcs/expression.cs [new file with mode: 0644]
mcs/bmcs/flowanalysis.cs [new file with mode: 0644]
mcs/bmcs/gen-il.cs [new file with mode: 0644]
mcs/bmcs/gen-treedump.cs [new file with mode: 0644]
mcs/bmcs/generic.cs [new file with mode: 0644]
mcs/bmcs/gmcs.exe.sources [new file with mode: 0644]
mcs/bmcs/iterators.cs [new file with mode: 0644]
mcs/bmcs/literal.cs [new file with mode: 0644]
mcs/bmcs/location.cs [new file with mode: 0644]
mcs/bmcs/mb-parser.cs [new file with mode: 0644]
mcs/bmcs/mb-parser.jay [new file with mode: 0644]
mcs/bmcs/mb-tokenizer.cs [new file with mode: 0644]
mcs/bmcs/modifiers.cs [new file with mode: 0644]
mcs/bmcs/module.cs [new file with mode: 0644]
mcs/bmcs/namespace.cs [new file with mode: 0644]
mcs/bmcs/parameter.cs [new file with mode: 0644]
mcs/bmcs/parser.cs [new file with mode: 0644]
mcs/bmcs/pending.cs [new file with mode: 0644]
mcs/bmcs/report.cs [new file with mode: 0644]
mcs/bmcs/rootcontext.cs [new file with mode: 0644]
mcs/bmcs/sample-hello.cs [new file with mode: 0644]
mcs/bmcs/statement.cs [new file with mode: 0644]
mcs/bmcs/support.cs [new file with mode: 0644]
mcs/bmcs/symbolwriter.cs [new file with mode: 0644]
mcs/bmcs/tree.cs [new file with mode: 0644]
mcs/bmcs/typemanager.cs [new file with mode: 0644]

diff --git a/mcs/bmcs/AssemblyInfo.cs b/mcs/bmcs/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..c442f03
--- /dev/null
@@ -0,0 +1,8 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+[assembly: AssemblyVersion("1.1.2")]
+[assembly: AssemblyTitle ("Mono C# Compiler")]
+[assembly: AssemblyDescription ("Mono C# Compiler with Generics")]
+[assembly: AssemblyCopyright ("2001, 2002, 2003 Ximian, Inc.")]
+[assembly: AssemblyCompany ("Ximian, Inc.")]
diff --git a/mcs/bmcs/ChangeLog b/mcs/bmcs/ChangeLog
new file mode 100644 (file)
index 0000000..52186c6
--- /dev/null
@@ -0,0 +1,19249 @@
+2004-12-12  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Unary.TryReduceNegative): Added support for
+       SByteConstant and ByteConstant.
+       (Unary.Reduce): Check error values from TryReduceNegative().
+
+2004-12-11  Martin Baulig  <martin@ximian.com>
+
+       * support.cs (ReflectionParameters.ParameterName): If we have a
+       `gpd', call `ParameterName' on it.
+
+       * parameter.cs (Parameter.GetParameterAttributes): New static method.
+
+       * pending.cs (PendingImplementation.DefineProxy): Call
+       DefineParameter() for all of the MethodBuilder's arguments.
+
+2004-12-09  Martin Baulig  <martin@ximian.com>
+
+       * doc.cs (DocUtil): Make this a static class.
+
+2004-12-09  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.InferType): Moved the type inference
+       implementation into TypeManager.
+
+       * generics.cs (TypeManager): Moved the type inference
+       implementation here.
+
+2004-12-09  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager): Make this a partial class.
+
+       * generics.cs
+       (TypeManager): Move the generics part of `TypeManager' here.
+
+2004-12-08  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.VerifyClsCompliance): Report a CS3003
+       instead of a CS3002 for properties and indexer.  Added CS3024
+       check for generic interfaces.
+
+       * attributes.cs (AttributeTester.AnalyzeTypeCompliance): Generic
+       instances are not CLS-compliant.
+
+2004-12-08  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay
+       (void_pointer_expression): New rule for `void*', `void**' etc.
+       (typeof_expression): Add `void_pointer_expression'; fixes #66846.       
+
+2004-12-08  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.InferType): Removed the hack for
+       MethodCore.MayUnify().  
+
+       * typemanager.cs (TypeManager.MayBecomeEqualGenericTypes): Make
+       this actually work.
+
+       * class.cs (MethodCore.MayUnify): Use
+       TypeManager.MayBecomeEqualGenericTypes().       
+
+2004-12-08  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Is.DoResolve, As.DoResolve): If we're a type
+       parameter, box it.  Fixes #69233.
+
+2004-12-08  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.CheckConstraints): Valuetypes always
+       have the ctor constraint.  Fixes #68326.
+
+2004-12-07  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * cs-parser.jay : interface comment was not consumed because of
+         extra opt_semicolon before doc handling.
+
+2004-12-03  Raja R Harinath  <rharinath@novell.com>
+
+       Fix test-327.cs, test-328.cs, and put in early infrastructure
+       for eventually fixing #52697.
+       * namespace.cs (NamespaceEntry.LookupForUsing): New method.
+       (NamespaceEntry.LookupNamespaceOrType): New method, refactored
+       from other methods.
+       (NamespaceEntry.Lookup): Remove 'ignore_using' flag.
+       (AliasEntry.Resolve, UsingEntry.Resolve): Use 'LookupForUsing'.
+       (VerifyUsing, error246): Update.
+       * rootcontext.cs (RootContext.NamespaceLookup): Just use
+       'NamespaceEntry.LookupNamespaceOrType'.
+
+2004-12-07  Martin Baulig  <martin@ximian.com>
+
+       * driver.cs: Call it "BETA SOFTWARE" :-)
+
+2004-12-06  Raja R Harinath  <rharinath@novell.com>
+
+       Fix crash on cs0657-17.cs.
+       * codegen.cs (CommonAssemblyModulClass.GetClsCompliantAttribute):
+       Use RootContext.Tree.Types, not 'new RootTypes ()'.
+       * attribute.cs (GlobalAttribute.CheckAttributeType): Narrow down
+       the case where the NamespaceEntry gets overwritten.
+
+2004-12-06  Marek Safar  <marek.safar@seznam.cz>
+
+       Fixed #69195, #56821
+       * ecore.cs (ResolveBoolean): Tiny refactoring.
+
+       * expression.cs (Binary.DoResolve): Add warning 429 and skipping
+       of right expression resolving when left is false constant and
+       operator is LogicalAnd OR true constant and operator is LogicalOr.
+
+       * statement.cs (ResolveUnreachable): Always reports warning.
+
+2004-12-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs: Distinguish between 1721 and 1722 (just a little help
+       for the programmer).
+
+2004-12-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * delegate.cs: Only allow this on new versions of the language. 
+
+2004-12-02  Duncan Mak  <duncan@ximian.com>
+
+       * ecore.cs (PropertyExpr.IsAccessorAccessible): Moved to
+       Expression class.
+       (Expression.IsAccessorAccessible): Moved from the PropertyExpr to
+       here as a static method. Take an additional bool out parameter
+       `must_do_cs1540_check' for signaling to InstanceResolve.
+       (PropertyExpr.InstanceResolve): Removed the `must_do_cs1540_check'
+       member field from PropertyExpr class and made it an argument of
+       the method instead.
+       (EventExpr.InstanceResolve): Copied from PropertyExpr, removed the
+       check for MarshalByRefObject, and report CS0122 instead of CS1540.
+       (EventExpr.DoResolve): Call IsAccessorAccessible on `add_accessor'
+       and `remove_accessor' as well as InstanceResolve: report CS0122
+       where applicable.
+
+       Fixes #70129.
+
+2004-12-07  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.AddToContainer): Report correct errors CS0694
+       and CS0692 where appropriate.
+
+2004-12-06  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodCore.MayUnify): Moved the CS0408 check here from
+       IsDuplicateImplementation() and improved it.
+
+       * expression.cs (Invocation.InferTypeArguments): Added
+       `Type[] inferred_class_types' argument (for MethodCore.MayUnify)
+       and removed the "ref" modifier from `infered_types'.
+
+       * decl.cs (MemberName.ToString): Removed the exception.
+
+2004-12-03  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * cs-tokenizer.cs : Only '////' is rejected. Other non-whitespace
+         comments are allowed.
+
+2004-12-03  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * delegate.cs: Add checks for subtypes in paramaters and return values
+       in VerifyMethod () to add support for Covariance/Contravariance
+       in delegates.
+       
+2004-12-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * report.cs: Remove extra closing parenthesis.
+
+       * convert.cs (Error_CannotImplicitConversion): If the name of the
+       types are the same, provide some extra information.
+
+2004-12-02  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #70102
+       * attribute.cs (Resolve): Improved implementation of params
+        attribute arguments.
+
+       * support.cs (ParameterData): Add HasParams to be faster.
+
+2004-12-02  Atsushi Enomoto  <atsushi@ximian.com>
+
+       all things are for /doc support:
+
+       * doc.cs: new file that supports XML documentation generation.
+       * mcs.exe.sources: added doc.cs.
+       * driver.cs:
+         Handle /doc command line option.
+         Report error 2006 instead of 5 for missing file name for /doc.
+         Generate XML documentation when required, after type resolution.
+       * cs-tokenizer.cs:
+         Added support for picking up documentation (/// and /** ... */),
+         including a new XmlCommentState enumeration.
+       * cs-parser.jay:
+         Added lines to fill Documentation element for field, constant,
+         property, indexer, method, constructor, destructor, operator, event
+         and class, struct, interface, delegate, enum.
+         Added lines to warn incorrect comment.
+       * rootcontext.cs :
+         Added Documentation field (passed only when /doc was specified).
+       * decl.cs:
+         Added DocComment, DocCommentHeader, GenerateDocComment() and
+         OnGenerateDocComment() and some supporting private members for
+         /doc feature to MemberCore.
+       * class.cs:
+         Added GenerateDocComment() on TypeContainer, MethodCore and Operator.
+       * delegate.cs:
+         Added overriden DocCommentHeader.
+       * enum.cs:
+         Added overriden DocCommentHeader and GenerateDocComment().
+
+2004-12-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * cfold.cs (ConstantFold.DoConstantNumericPromotions): After
+       unwrapping the enumeration values, chain to
+       DoConstantNumericPromotions again, so we can promote things to the
+       fundamental types (takes care of enums that are bytes, sbytes).
+
+       Fixes bug #62054.
+
+2004-12-01  Raja R Harinath  <rharinath@novell.com>
+
+       * attribute.cs (Attribute.CheckAttributeType): Remove complain flag.
+       Fix long-standing bug in type-lookup.  Use FindType instead of
+       LookupType when ec.ResolvingTypeTree.
+       (Attribute.ResolveType, Attribute.Resolve)
+       (Attribute.DefinePInvokeMethod,GlobalAttribute.CheckAttributeType):
+       Update to changes.
+       (Attributes.Search): Remove internal version.  Update.
+       (Attributes.SearchMulti): Update.
+       (Attributes.GetClsCompliantAttribute): Remove.
+       (Attributes.GetIndexerNameAttribute): Remove.
+       * decl.cs (MemberCore.GetClsCompliantAttributeValue): Update to changes.
+       (DeclSpace.GetClsCompliantAttributeValue): Likewise.
+       * class.cs (Indexer.Define): Likewise.
+
+2004-12-01  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #68790
+       * ecore.cs: CheckMarshallByRefAccess new virtual method for testing
+       MarshallByReference members access.
+
+       * expression.cs: Use CheckMarshallByRefAccess;
+       Better error CS0197 message.
+
+       * report.cs: Print whole related error message.
+
+2004-11-29  Marek Safar  <marek.safar@seznam.cz>
+
+       * class (GetClassBases): Better error 60 report.
+       (EventProperty): Disabled warning 67 detection.
+
+2004-11-29  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #60324
+       * cfold.cs (Assign.DoResolve): Add subtraction for DecimalConstant.
+
+       * constant.cs (DecimalConstant.Emit): Don't use int ctor for
+       precise values.
+
+2004-11-29  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #49488
+       * assign.cs (Assign.DoResolve): Add error 1648, 1650 report.
+
+       * decl.cs (MemberCore.MemberName): Error 1648 in compiler.
+
+2004-11-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs (Attribute.Resolve): Refine error reporting and
+       report a cs0117 if the identifier does not exist, to distinguish
+       from 0617 which is a miss-use of the actual identifier.
+
+       * ecore.cs (EventExpr.Emit): Refine error report and distinguish
+       between cs0070 and cs0079.
+
+       * class.cs (MemberBase.DoDefine): When reporting a wrong
+       accessibility level, we use MethodCore to compare instead of
+       Method (this was a regression in some refactoring effort).
+
+       So now we correctly report cs0056 again.
+
+       * convert.cs (ImplicitReferenceConversion): Corrected typo, I was
+       testing the target_type (which was known to be object_type) and
+       not the source type (which is anonymous_method).
+
+       Fixed reporting of error cs1660.
+
+       * expression.cs (UserCast.Source): Expose the underlying cast.
+
+       * statement.cs (Switch.SwitchGoverningType): Sort the list of
+       allowed types to find a match to int32 first (most common).
+
+       In addition, it ignores any ImplicitUserConversions that did an
+       internal implicit conversion (as the switch statement allows only
+       one integral conversion to exist).
+
+       * class.cs (PartialContainer.Create): rename `name' to
+       `member_name' for clarity.  Then replace the string calls with a
+       call to MemberName.GetPartialName, as now using
+       MemberName.ToString is an error (this is due to the side effects
+       it had, that were fixed in the past).
+
+       This will restore the error reporting on a number of partial class
+       errors that were missusing this (and getting an exception as a
+       results, which is now just a plain textual warning, because
+       yyparse debug output would crash otherwise).
+
+2004-11-26  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile (PROGRAM_INSTALL_DIR): Remove.
+
+2004-11-25  Ben Maurer  <bmaurer@ximian.com>
+
+       * rootcontext.cs (LookupType): Make sure to cache lookups that
+       don't give us a negative result. This saves about 5% of corlib
+       compilation time.
+
+2004-11-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * report.cs (AbstractMessage.Print): messages are sent to stderr
+
+       * class.cs (TypeContainer.GetClassBases): It is an error to have a
+       non-interface in the list of interfaces (at this point, either
+       parent was properly set, or a base class is being listed in the
+       interfaces section).
+
+       This flags error 1722, and resolves the crash from bug 69259.
+
+2004-11-25  Ben Maurer  <bmaurer@ximian.com>
+
+       * statement.cs (Using.EmitExpressionFinally): make this work right
+       for valuetypes. Fixes 69926.
+
+2004-11-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * const.cs (Const.ChangeType): Cope with the "0 literal can be
+       converted to an enum" here, before we try to change the underlying
+       type.  This code exists, but it is a different code path than the
+       one used while encoding constants.
+
+       (ImplicitReferenceConversionExists): In addition, resynchronized
+       the code here, so it matches the same code in
+       ImplicitReferenceConversionExists for the `from any class-type S
+       to any interface-type T'.       
+
+2004-11-25  Marek Safar  <marek.safar@seznam.cz>
+
+       * cfold.cs (BinaryFold): Add addition for DecimalConstant.
+
+2004-11-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Use verbosity accordingly. 
+
+2004-11-24  Marek Safar  <marek.safar@seznam.cz>
+
+       * expression.cs (Unary.ResolveOperator): Do not report warning;
+       AddressOf reads from variable.
+       
+       (LocalVariableReferences.DoResolveBase): Improved my previous fix.
+
+2004-11-24  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #69462
+
+       * attribute.cs (Attributable): Removed CheckTargets.
+       (Attributes.Emit): Explicit attribute targets are tested here.
+
+       * class.cs (EventField.ValidAttributeTargets): Explicit target "field" is
+       not enabled for interfaces.
+
+       * codegen.cs (CommonAssemblyModulClass.AddAttributes): Removed CheckTargets.
+       (GetAssemblyName): Ouch next bug there.
+
+2004-11-23  Carlos Alberto Cortez <calberto.cortez@gmail.com>
+
+       * expression.cs: Error 275 added.
+       
+2004-11-23  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #69177 (Implemented decimal constant support)
+
+       * cfold.cs (DoConstantNumericPromotions: Add DecimalConstant.
+       (BinaryFold): Add DecimalConstant.
+
+       * const.cs (Define): Decimal constant 
+       (is not constant.
+       (ChangeType): Add decimal type handling.
+       (LookupConstantValue): Don't set value for decimal type but
+       emit DecimalConstantAttribute. Needed for constant optimization.
+
+       * constant.cs (ToDecimal): New method.
+       (ConvertToDecimal): New method.
+       (IntConstant): Implemented ConvertToDecimal.
+       (DecimalConstant.Emit): Emit optimized version for decimals in
+       int range.
+
+       * expression.cs (ResolveOperator): Changed order of constant
+       reduction to work correctly with native types which have
+       overloaded operators.
+       (ResolveMemberAccess): Extract constant value from attribute
+       for decimal type.
+
+       * rootcontext.cs (ResolveCore): Add DecimalConstantAttribute.
+
+       * typemanager.cs (TypeManager): Add decimal_constant_attribute_type,
+       void_decimal_ctor_int_arg, decimal_constant_attribute_ctor.
+       (ChangeType): Decimal is special.
+       (TypeToCoreType): Add decimal type.
+
+2004-11-22  Marek Safar  <marek.safar@seznam.cz>
+
+       * convert.cs (ImplicitConversionRequired): Add error cs0642 for
+       decimal types.
+
+2004-11-22  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (EventField.ApplyAttributeBuilder): Fix error
+       test cs1667-5.cs.
+
+2004-11-19  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (MemberBase.DoDefine): Fix error cs0508 report.
+
+       * pending.cs (PendingImplementation): Grab only interfaces.
+
+2004-11-19  Marek Safar  <marek.safar@seznam.cz>
+
+       * statement.cs (ForeachHelperMethods): Add location member and
+       error 202 detection.
+
+2004-11-18  Marek Safar  <marek.safar@seznam.cz>
+
+       * expression.cs (DoResolveBase): Fixed wrong warning for out
+       variables.
+
+2004-12-04  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs (Convert.TypeParameter_to_Null): Use the constraints
+       to check whether the conversion is ok.
+
+       * typemanager.cs (TypeManager.GetTypeArguments): Just return
+       `Type.EmptyTypes' if we're not a generic TypeContainer.
+
+2004-11-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * convert.cs (ImplicitReferenceConversionExists): A surprisingly
+       old bug: when converting from the null literal to a pointer,
+       return an EmptyCast, not the NullLiteral.
+
+       This fixes #69921, the recent null_type changes probably made this
+       bug more prominent.
+
+2004-12-03  Martin Baulig  <martin@ximian.com>
+
+       * delegate.cs (NewDelegate.DoResolve): If we have an anonymous
+       method as our child, call AnonymousMethod.Compatible() on it.
+
+2004-12-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (FieldBase): Use an unused bit field from the field to
+       encode the `has_offset' property from the FieldMember.  This saves
+       a couple of Ks on bootstrap compilation.
+
+       * delegate.cs (NewDelegate.DoResolve): If we have an anonymous
+       method as our child, return the AnonymousMethod resolved
+       expression.
+
+       * expression.cs (New.DoResolve): Allow return values from
+       NewDelegate to also include AnonymousMethods.
+
+       Fixes #70150.
+
+2004-11-29  Raja R Harinath  <rharinath@novell.com>
+
+       * decl.cs (MemberCore.MemberName): Remove readonly to fix an error
+       cs1648 report.
+       * rootcontext.cs (ResolveCore::interfaces_first_stage): Add
+       System.Runtime.InteropServices._Exception, since it's a base
+       interface of the core type System.Exception in the net_2_0 profile.
+
+2004-11-27  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (Expression.StoreFromPtr): Use `stobj' for generic parameters.
+
+2004-11-26  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile: Convert to use executable.make.
+       * gmcs.exe.sources: New.
+
+2004-11-25  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.InferType): Added support for byref types.
+
+2004-11-25  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Foreach.FetchMethodMoveNext): Wrap `mi.ReturnType'
+       in TypeManager.TypeToCoreType().
+
+2004-11-25  Martin Baulig  <martin@ximian.com>
+
+       * iterators.cs (Iterator.DoDefineMembers): Override and lookup the
+       "Dispose" method from the `current_type'.
+       (Iterator.EmitMoveNext): Use the `dispose_method' we looked up in
+       DoDefineMembers() instead of using the MethodBuilder; this is
+       required for generic iterators.
+
+       * class.cs (TypeContainer.DoDefineMembers): Make this virtual.
+
+2004-11-24  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (Expression.LoadFromPtr): Use `ldobj' for generic parameters.
+
+2004-11-20  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.InferType): Correctly infer generic
+       instances; see gen-103.cs.
+       (Invocation.InferTypeArguments): If a generic method doesn't have
+       any unbound type parameters, we don't need to infer anything.
+
+2004-11-19  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile (gmcs.exe): Update to new location of bootstrap mcs.exe.
+
+2004-11-17  Raja R Harinath  <rharinath@novell.com>
+
+       * typemanager.cs (TypeHandle.GetTypeHandle): Make private.
+       (TypeHandle.GetMemberCache): New.
+       (TypeHandle.TypeHandle): Update.
+       (TypeManager.LookupMemberCache): Rewritten from LookupMemberContainer.
+       (TypeManager.LookupParentInterfacesCache):
+       Rename from LookupInterfaceCache.  Optimize slightly.
+       (TypeManager.MemberLookup_FindMembers): Update.
+       * decl.cs (MemberCache.MemberCache): Set Container to null in the
+       multi-type variant.
+       (AddCacheContents): Rename from AddHashtable.
+       * class.cs (TypeContainer.parent_container): Remove.
+       (TypeContainer.VerifyClsCompliance): Don't use parent_container.
+       (TypeContainer.DoDefineMembers): Don't initialize it.
+       Update to name changes.
+       
+2004-11-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (MethodCore.CheckAccessModifiers): New helper routine
+       that factors the code to check access modifiers on override.  
+
+       (PropertyBase): Use the code here.
+
+       Patch from Lluis S'anchez, fixes bug #69361.
+
+2004-11-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * anonymous.cs (AnonymousMethod.Error_AddressOfCapturedVar): New
+       routine that is used to report the use of a captured variable
+       whose address has been taken.
+
+       There are two checks: one when variables are being captured and
+       the other check is when the address of a variable is taken. 
+       
+       (because an anonymous methods might be resolved before *or* after
+       the address has been taken) and 
+
+       * expression.cs (Conditional.DoResolve): Remove the special
+       casing that Martin added to trueExpr and falseExpr being both
+       NullLiteral.  We get the right behavior now just by introducing
+       the null_type into the compiler. 
+
+       * convert.cs (ExplicitConversion): Change the code to use
+       null_type instead of testing `expr is NullLiteral'.
+       (ImplicitConversionStandard): use null_type too.
+       (ImplicitReferenceConversionExists): use null_type too.
+       (ImplicitReferenceConversion): use null_type too.
+
+       * literal.cs: The type of `NullLiteral' is now null_type instead
+       of object_type. 
+       (Resolve): Set the type here.
+
+       * typemanager.cs: Introduce null_type.
+
+2004-11-18  Martin Baulig  <martin@ximian.com>
+
+       * rootcontext.cs
+       (RootContext.LookupType): Return a `Type', not a `TypeExpr'.
+
+2004-11-18  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (TypeExpr.DoResolveAsTypeStep): Make this protected.
+
+2004-11-18  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (Constraints.Resolve): Take an `EmitContext' instead
+       of a `DeclSpace'.  If one of our constraints is a `ConstructedType',
+       call ResolveConstructedType() on it to resolve it without checking
+       constraints.
+       (Constraints.ResolveTypes): Check them here.
+       (ConstructedType.DoResolveAsTypeStep): Fully resolve ourselves,
+       but don't check constraints.
+       (ConstructedType.ResolveAsTypeTerminal): Override this and also
+       check constraints here.
+       (ConstructedType.ResolveConstructedType): New public method.  This
+       is called from DoResolveAsTypeStep() and Constraints.Resolve() to
+       resolve ourselves without checking constraints.
+
+       * ecore.cs (Expression.ResolveAsTypeTerminal): Make this virtual.
+
+2004-11-18  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs
+       (DeclSpace.CurrentType): Changed type from `TypeExpr' to `Type'.
+
+       * delegate.cs (Delegate.DefineType): Always create the EmitContext.
+
+2004-11-18  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (TypeExpr.ResolveType): Removed.
+       (Expression.ResolveAsTypeTerminal): We always return a fully
+       resolved `TypeExpr', so we can just access its `Type'.
+
+       * class.cs (TypeContainer.DefineType): Resolve `CurrentType' here.
+
+2004-11-17  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (IAlias.Type): Replaced with ResolveAsType() to make
+       sure we don't return any unresolved TypeExpr's.
+       (TypeAliasExpression): The .ctor now takes an `IAlias' instead of
+       a `TypeExpr'.
+       (Expression.ResolveAsTypeTerminal): Make sure `te.Type != null'.
+
+       * expression.cs (MemberAccess.ResolveAsTypeStep): Don't return any
+       unresolved `ConstructedType's.
+
+2004-11-17  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (TypeExpr.ResolveType): Don't make this virtual.
+
+2004-11-17  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs
+       (Expression.ResolveAsTypeTerminal): Removed the `bool silent' argument.
+
+       * decl.cs (DeclSpace.ResolveType): Removed.
+       (DeclSpace.ResolveTypeExpr): Removed the `bool silent' argument.
+
+2004-11-17  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCache.AddHashtable): Add entries in the opposite
+       direction, like FindMembers() does.  Fixes #69546, testcase is in
+       test-315.cs.    
+
+2004-11-16  Martin Baulig  <martin@ximian.com>
+
+       This is based on a patch from Marek Safar, see bug #69082.
+       Fixes bugs #63705 and #67130.
+
+       * typemanager.cs (TypeManager.LookupInterfaceCache): New public
+       method; create a MemberCache for an interface type and cache the
+       result.
+
+       * decl.cs (IMemberContainer.ParentContainer): Removed.
+       (IMemberContainer.ParentCache): New property.
+       (MemberCache.SetupCacheForInterface): Removed.
+       (MemberCache..ctor): Added .ctor which takes a `Type[]'; use this
+       to create a cache for an interface's "parent".
+
+       * class.cs (TypeContainer.DoDefineMembers): Setup cache for
+       interfaces too.
+
+2004-11-14  Ben Maurer  <bmaurer@ximian.com>
+
+       * statement.cs: Avoid adding bools to a hashtable.
+
+2004-11-15  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberName.GetPartialName): Removed, use GetTypeName() instead.
+
+2004-11-11  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.GetMethodName): New method.
+
+       * class.cs (MethodData.Define): Include the generic arity in the
+       name of an explicit interface; also add it to the method name.
+
+       * pending.cs (PendingImplementation.InterfaceMethod): The method
+       name now includes the generic arity.
+
+2004-11-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Invocation.OverloadResolve): Flag error if we are
+       calling an unsafe method from a safe location.
+
+2004-11-06  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix #69167
+       * codegen.cs (ApplyAttributeBuilder): Do not return; it is only warning.
+
+2004-11-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * namespace.cs (VerifyUsing): use GetPartialName instead of
+       ToString. 
+
+2004-11-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Return.Resolve): Fix regression in typo: if
+       `in_exc', we have to request a NeedReturnLabel, this was a typo
+       introduced in the anonymous method check-in.  Fixes #69131.
+
+       * Indexers were using the ShortName when defining themselves,
+       causing a regression in the compiler bootstrap when applying the
+       patch from 2004-11-02 (first part), now they use their full name
+       and the bug is gone.
+
+2004-11-04  Zoltan Varga  <vargaz@freemail.hu>
+
+       * driver.cs: Strip the path from the names of embedded resources. Fixes
+       #68519.
+
+2004-11-04  Raja R Harinath  <rharinath@novell.com>
+
+       Fix error message regression: cs0104-2.cs.
+       * namespace.cs (NamespaceEntry.Lookup): Remove 'silent' flag.
+       (AliasEntry.Resolve): Update.
+       * rootcontext.cs (RootContext.NamespaceLookup): Update.  Remove
+       'silent' flag.
+       (RootContext.LookupType): Update.
+
+2004-11-03  Carlos Alberto Cortez <carlos@unixmexico.org>
+
+       * cs-parser.jay: Add support for handling accessor modifiers
+       * class: Add support port accessor modifiers and error checking,
+       define PropertyMethod.Define as virtual (not abstract anymore)
+       * ecore.cs: Add checking for proeprties access with access modifiers
+       * iterators.cs: Modify Accessor constructor call based in the modified
+       constructor
+2004-11-02  Ben Maurer  <bmaurer@ximian.com>
+
+       * expression.cs (StringConcat): Handle being called twice,
+       as when we have a concat in a field init with more than two
+       ctors in the class
+
+2004-11-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Event.Define, Indexer.Define, Property.Define): Do not
+       special case explicit implementations, we should always produce
+       the .property or .event declaration.
+       
+       * decl.cs (MemberName): Renamed GetFullName to GetPartialName
+       since it will not return correct data if people use this
+       unresolved in the presence of using statements (see test-313).
+
+       * class.cs (MethodData.Define): If we are an explicit interface
+       implementation, set the method name to the full name of the
+       interface plus the name of the method.  
+
+       Notice that using the method.MethodName.GetFullName() does not
+       work, as it will only contain the name as declared on the source
+       file (it can be a shorthand in the presence of using statements)
+       and not the fully qualifed type name, for example:
+
+       using System;
+
+       class D : ICloneable {
+               object ICloneable.Clone ()  {
+               }
+       }
+
+       Would produce a method called `ICloneable.Clone' instead of
+       `System.ICloneable.Clone'.
+
+       * namespace.cs (Alias.Resolve): Use GetPartialName.
+       
+2004-11-01  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Add error 1055 report.
+
+2004-11-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs (Assign.DoResolve): Only do the transform of
+       assignment into a New if the types are compatible, if not, fall
+       through and let the implicit code deal with the errors and with
+       the necessary conversions. 
+
+2004-11-01  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Add error 1031 report.
+
+       * cs-tokenizer.cs: Add location for error 1038.
+
+2004-10-31  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Add error 1016 report.
+
+2004-10-31  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Add errors 1575,1611 report.
+
+2004-10-31  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Add error 1001 report.
+
+2004-10-31  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix #68850
+       * attribute.cs (GetMarshal): Add method argument for
+       caller identification.
+
+       * class.cs, codegen.cs, enum.cs, parameter.cs: Added
+       agument for GetMarshal and RuntimeMissingSupport.
+
+2004-10-31  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs (ExtractSecurityPermissionSet): Removed
+       TypeManager.code_access_permission_type.
+
+       * typemanager.cs: Removed TypeManager.code_access_permission_type.
+
+2004-10-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (LocalVariableReference.DoResolveLValue): Check
+       for obsolete use of a variable here.   Fixes regression on errors
+       cs0619-25 and cs0619-26.
+
+2004-10-27  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix #62358, implemented security attribute encoding.
+
+       * attribute.cs (Attribute.CheckSecurityActionValididy): New method.
+       Tests permitted SecurityAction for assembly or other types.
+       (Assembly.ExtractSecurityPermissionSet): New method. Transforms
+       data from SecurityPermissionAttribute to PermisionSet class.
+
+       * class.cs (ApplyAttributeBuilder): Added special handling
+       for System.Security.Permissions.SecurityAttribute based types.
+
+       * codegen.cs (AssemblyClass.ApplyAttributeBuilder): Added
+       special handling for System.Security.Permissions.SecurityAttribute
+       based types.
+
+       * enum.cs (ApplyAttributeBuilder): Added special handling
+       for System.Security.Permissions.SecurityAttribute based types.
+
+       * parameter.cs (ApplyAttributeBuilder): Added special handling
+       for System.Security.Permissions.SecurityAttribute based types.
+
+       * rootcontext.cs: Next 2 core types.
+
+       * typemanager.cs (TypeManager.security_permission_attr_type):
+       Built in type for the SecurityPermission Attribute.
+       (code_access_permission_type): Build in type.
+
+2004-10-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (LocalVariableReference.DoResolveBase, Emit):
+       Remove the tests for `ec.RemapToProxy' from here, and encapsulate
+       all of this information into
+       EmitContext.EmitCapturedVariableInstance.
+       
+       * codegen.cs (EmitCapturedVariableInstance): move here the
+       funcionality of emitting an ldarg.0 in the presence of a
+       remapping.   This centralizes the instance emit code.
+
+       (EmitContext.EmitThis): If the ScopeInfo contains a THIS field,
+       then emit a load of this: it means that we have reached the
+       topmost ScopeInfo: the one that contains the pointer to the
+       instance of the class hosting the anonymous method.
+
+       * anonymous.cs (AddField, HaveCapturedFields): Propagate field
+       captures to the topmost CaptureContext.
+
+2004-10-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (LocalVariableReference): Move the knowledge about
+       the iterators into codegen's EmitCapturedVariableInstance.
+
+2004-10-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs (EmitContext.ResolveTopBlock): Emit a 1643 when not
+       all code paths return a value from an anonymous method (it is the
+       same as the 161 error, but for anonymous methods).
+
+2004-10-08  Miguel de Icaza  <miguel@ximian.com>
+
+       The introduction of anonymous methods in the compiler changed
+       various ways of doing things in the compiler.  The most
+       significant one is the hard split between the resolution phase
+       and the emission phases of the compiler.
+
+       For instance, routines that referenced local variables no
+       longer can safely create temporary variables during the
+       resolution phase: they must do so from the emission phase,
+       since the variable might have been "captured", hence access to
+       it can not be done with the local-variable operations from the runtime.
+       
+       * statement.cs 
+
+       (Block.Flags): New flag `IsTopLevel' to indicate that this block
+       is a toplevel block.
+
+       (ToplevelBlock): A new kind of Block, these are the blocks that
+       are created by the parser for all toplevel method bodies.  These
+       include methods, accessors and anonymous methods.
+
+       These contain some extra information not found in regular blocks:
+       A pointer to an optional CaptureContext (for tracking captured
+       local variables and parameters).  A pointer to the parent
+       ToplevelBlock.
+       
+       (Return.Resolve): Catch missmatches when returning a value from an
+       anonymous method (error 1662).
+       Invoke NeedReturnLabel from the Resolve phase instead of the emit
+       phase.
+
+       (Break.Resolve): ditto.
+
+       (SwitchLabel): instead of defining the labels during the
+       resolution phase, we now turned the public ILLabel and ILLabelCode
+       labels into methods called GetILLabelCode() and GetILLabel() that
+       only define the label during the Emit phase.
+
+       (GotoCase): Track the SwitchLabel instead of the computed label
+       (its contained therein).  Emit the code by using
+       SwitchLabel.GetILLabelCode ().
+
+       (LocalInfo.Flags.Captured): A new flag has been introduce to track
+       whether the Local has been captured or not.
+
+       (LocalInfo.IsCaptured): New property, used to tell whether the
+       local has been captured.
+       
+       * anonymous.cs: Vastly updated to contain the anonymous method
+       support.
+
+       The main classes here are: CaptureContext which tracks any
+       captured information for a toplevel block and ScopeInfo used to
+       track the activation frames for various local variables.   
+
+       Each toplevel block has an optional capture context associated
+       with it.  When a method contains an anonymous method both the
+       toplevel method and the anonymous method will create a capture
+       context.   When variables or parameters are captured, they are
+       recorded on the CaptureContext that owns them, for example:
+
+       void Demo () {
+            int a;
+            MyDelegate d = delegate {
+                a = 1;
+            }
+       }
+
+       Here `a' will be recorded as captured on the toplevel
+       CapturedContext, the inner captured context will not have anything
+       (it will only have data if local variables or parameters from it
+       are captured in a nested anonymous method.
+
+       The ScopeInfo is used to track the activation frames for local
+       variables, for example:
+
+       for (int i = 0; i < 10; i++)
+               for (int j = 0; j < 10; j++){
+                  MyDelegate d = delegate {
+                       call (i, j);
+                  }
+               }
+
+       At runtime this captures a single captured variable `i', but it
+       captures 10 different versions of the variable `j'.  The variable
+       `i' will be recorded on the toplevel ScopeInfo, while `j' will be
+       recorded on a child.  
+
+       The toplevel ScopeInfo will also track information like the `this'
+       pointer if instance variables were referenced (this is necessary
+       as the anonymous method lives inside a nested class in the host
+       type of the method). 
+
+       (AnonymousMethod): Expanded to track the Toplevel, implement
+       `AnonymousMethod.Compatible' to tell whether an anonymous method
+       can be converted to a target delegate type. 
+
+       The routine now also produces the anonymous method content
+
+       (AnonymousDelegate): A helper class that derives from
+       DelegateCreation, this is used to generate the code necessary to
+       produce the delegate for the anonymous method that was created. 
+
+       * assign.cs: API adjustments for new changes in
+       Convert.ImplicitStandardConversionExists.
+
+       * class.cs: Adjustments to cope with the fact that now toplevel
+       blocks are of type `ToplevelBlock'. 
+
+       * cs-parser.jay: Now we produce ToplevelBlocks for toplevel blocks
+       insteda of standard blocks.
+
+       Flag errors if params arguments are passed to anonymous methods.
+
+       * codegen.cs (EmitContext): Replace `InAnonymousMethod' with
+       `CurrentAnonymousMethod' which points to the current Anonymous
+       Method.  The variable points to the AnonymousMethod class that
+       holds the code being compiled.  It is set in the new EmitContext
+       created for the anonymous method.
+
+       (EmitContext.Phase): Introduce a variable and an enumeration to
+       assist in enforcing some rules about when and where we are allowed
+       to invoke certain methods (EmitContext.NeedsReturnLabel is the
+       only one that enfonces this right now).
+
+       (EmitContext.HaveCaptureInfo): new helper method that returns
+       whether we have a CapturedContext initialized.
+
+       (EmitContext.CaptureVariable): New method used to register that a
+       LocalInfo must be flagged for capturing. 
+
+       (EmitContext.CapturedParameter): New method used to register that a
+       parameters must be flagged for capturing. 
+       
+       (EmitContext.CapturedField): New method used to register that a
+       field must be flagged for capturing. 
+
+       (EmitContext.HaveCapturedVariables,
+       EmitContext.HaveCapturedFields): Return whether there are captured
+       variables or fields. 
+
+       (EmitContext.EmitMethodHostInstance): This is used to emit the
+       instance for the anonymous method.  The instance might be null
+       (static methods), this (for anonymous methods that capture nothing
+       and happen to live side-by-side with the current method body) or a
+       more complicated expression if the method has a CaptureContext.
+
+       (EmitContext.EmitTopBlock): Routine that drives the emission of
+       code: it will first resolve the top block, then emit any metadata
+       and then emit the code.  The split is done so that we can extract
+       any anonymous methods and flag any captured variables/parameters.
+       
+       (EmitContext.ResolveTopBlock): Triggers the resolution phase,
+       during this phase, the ILGenerator should not be used as labels
+       and local variables declared here might not be accessible to any
+       code that is part of an anonymous method.  
+
+       Exceptions to this include the temporary variables that are
+       created by some statements internally for holding temporary
+       variables. 
+       
+       (EmitContext.EmitMeta): New routine, in charge of emitting all the
+       metadata for a cb
+
+       (EmitContext.TemporaryReturn): This method is typically called
+       from the Emit phase, and its the only place where we allow the
+       ReturnLabel to be defined other than the EmitMeta.  The reason is
+       that otherwise we would have to duplicate a lot of logic in the
+       Resolve phases of various methods that today is on the Emit
+       phase. 
+
+       (EmitContext.NeedReturnLabel): This no longer creates the label,
+       as the ILGenerator is not valid during the resolve phase.
+
+       (EmitContext.EmitThis): Extended the knowledge in this class to
+       work in anonymous methods in addition to iterators. 
+
+       (EmitContext.EmitCapturedVariableInstance): This emits whatever
+       code is necessary on the stack to access the instance to a local
+       variable (the variable will be accessed as a field).
+
+       (EmitContext.EmitParameter, EmitContext.EmitAssignParameter,
+       EmitContext.EmitAddressOfParameter): Routines to support
+       parameters (not completed at this point). 
+       
+       Removals: Removed RemapLocal and RemapLocalLValue.  We probably
+       will also remove the parameters.
+
+       * convert.cs (Convert): Define a `ConstantEC' which points to a
+       null.  This is just to prefity some code that uses
+       ImplicitStandardConversion code and do not have an EmitContext
+       handy.
+
+       The idea is to flag explicitly that at that point in time, it is
+       known that the conversion will not trigger the delegate checking
+       code in implicit conversions (which requires a valid
+       EmitContext). 
+
+       Everywhere: pass new EmitContext parameter since
+       ImplicitStandardConversionExists now requires it to check for
+       anonymous method conversions. 
+
+       (Convert.ImplicitStandardConversionExists): If the type of an
+       expression is the anonymous_method_type, and the type is a
+       delegate, we invoke the AnonymousMethod.Compatible method to check
+       whether an implicit conversion is possible. 
+
+       (Convert.ImplicitConversionStandard): Only do implicit method
+       group conversions if the language level is not ISO_1.
+
+       * delegate.cs (Delegate.GetInvokeMethod): Common method to get the
+       MethodInfo for the Invoke method.  used by Delegate and
+       AnonymousDelegate.
+
+       * expression.cs (Binary.DoNumericPromotions): only allow anonymous
+       method conversions if the target type is a delegate.
+
+       Removed extra debugging nops.
+
+       (LocalVariableReference): Turn the `local_info' into a public
+       field. 
+
+       Add `prepared' field, the same hack used for FieldExprs to cope
+       with composed assignments, as Local variables do not necessarily
+       operate purely on the stack as they used to: they can be captured
+       fields. 
+
+       Add `temp' for a temporary result, like fields.
+
+       Refactor DoResolve and DoResolveLValue into DoResolveBase.
+
+       It now copes with Local variables that are captured and emits the
+       proper instance variable to load it from a field in the captured
+       case. 
+
+       (ParameterReference.DoResolveBase): During the resolve phase,
+       capture parameters if we are in an anonymous method.
+
+       (ParameterReference.Emit, ParameterReference.AddressOf): If in an
+       anonymous method, use the EmitContext helper routines to emit the
+       parameter reference.
+
+       * iterators.cs: Set RemapToProxy to true/false during the
+       EmitDispose class.
+
+       * parameters.cs (GetParameterByName): New helper method. 
+
+       * typemanager.cs (anonymous_method_type) a new type that
+       represents an anonyous method.  This is always an internal type,
+       used as a fencepost to test against the anonymous-methodness of an
+       expression. 
+       
+2004-10-20  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (MethodCore.CheckBase): Add errors 505, 533, 544,
+       561 report.
+       (PropertyBase.FindOutParentMethod): Add errors 545, 546 report.
+
+2004-11-10  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.BetterFunction): If two methods have
+       equal parameter types, but only one of them is generic, the
+       non-generic one wins.
+       (New.DoResolve): Don't set `is_struct' to false if we're a generic
+       instance; just use `Type.IsValueType' to determine whether
+       something is a struct or not.
+       (MemberAccess.DoResolveAsTypeStep): Don't modify the `args' field,
+       so we can be called multiple times.
+
+2004-11-10  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (TypeParameter.DefineConstraints): New public method.
+       (TypeParameter.CheckAccessLevel): Override this and return true.
+       (ConstructedType.ResolveType): Renamed to DoResolveType(), don't
+       override ResolveType() anymore.
+       (ConstructedType.DoResolveAsTypeStep): Call DoResolveType() here.
+
+2004-11-10  Martin Baulig  <martin@ximian.com>
+
+       * rootcontext.cs (RootContext.LookupType): If we're a nested type,
+       call DeclSpace.ResolveNestedType() on it.
+
+2004-11-10  Martin Baulig  <martin@ximian.com>
+
+       * support.cs (ReflectionParameters.ParameterModifier): If `gpd' is
+       non-null, call ParameterModifier() on it.
+
+2004-11-10  Martin Baulig  <martin@ximian.com>
+
+       * iterators.cs
+       (Iterators): Added `current_type' and `this_type' fields.
+       (Iterators.DefineIterator): Create a new EmitContext and store it
+       in `ec'; compute `this_type'.
+
+2004-11-10  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs
+       (TypeManager.IsPrivateAccessible): New public method.
+       (Closure.Filter): Use IsPrivateAccessible() instead of IsEqual().
+
+2004-11-10  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.DefineType): Call
+       TypeBuilder.DefineGenericParameters() before resolving the type
+       parameters.
+       (MethodData.parent_method): New protected field.
+       (MethodData..ctor): Added `MethodInfo parent_method' argument.
+       (MethodData.Define): Compute `parent_method'.
+
+       * decl.cs
+       (MemberCore.GetObsoleteAttribute): Don't create a new EmitContext.
+       (MemberCore.GetClsCompliantAttributeValue): Likewise.
+       (DeclSpace.ec): New protected field; store the EmitContext here.
+       (DeclSpace.EmitContext): New public property.
+       (DeclSpace.ResolveType): Un-comment from the [Obsolte] attribute.
+       (DeclSpace.ResolveNestedType): New public method.
+       (DeclSpace.ResolveTypeExpr): Just call ResolveAsTypeTerminal() here.
+       (DeclSpace.NestedAccessible): Added `Type tb' argument.
+       (DeclSpace.FamilyAccessible): Likewise.
+       (DeclSpace.FindType): Call ResolveNestedType() for nested types.
+       (DeclSpace.GetClsCompliantAttributeValue): Don't create a new
+       EmitContext.
+
+       * delegate.cs (Delegate.Define): Store the EmitContext in the `ec'
+       field.
+
+       * enum.cs (Enum.Define): Store the EmitContext in the `ec' field.
+       (Enum.Emit): Don't create a new EmitContext.
+
+2004-10-18  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Fixed.Resolve): Don't access the TypeExpr's
+       `Type' directly, but call ResolveType() on it.
+       (Catch.Resolve): Likewise.
+       (Foreach.Resolve): Likewise.
+
+2004-10-18  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Cast.DoResolve): Don't access the TypeExpr's
+       `Type' directly, but call ResolveType() on it.
+       (Probe.DoResolve): Likewise.
+       (ArrayCreation.LookupType): Likewise.
+       (TypeOf.DoResolve): Likewise.
+       (SizeOf.DoResolve): Likewise.
+
+2004-10-18  Raja R Harinath  <rharinath@novell.com>
+
+       * class.cs (FieldMember.DoDefine): Reset ec.InUnsafe after doing
+       the ResolveType.
+
+2004-10-17  John Luke  <john.luke@gmail.com>
+
+       * class.cs (Operator.GetSignatureForError): use CSharpName
+
+       * parameter.cs (Parameter.GetSignatureForError): Returns
+       correct name even if was not defined.
+
+2004-10-13  Raja R Harinath  <rharinath@novell.com>
+
+       Fix #65816.
+       * class.cs (TypeContainer.EmitContext): New property.
+       (DefineNestedTypes): Create an emitcontext for each part.
+       (MethodCore.DoDefineParameters): Use container's emitcontext.
+       Pass type array to InternalParameters.
+       (MemberBase.DoDefine): Use container's emitcontext.
+       (FieldMember.Define): Likewise.
+       (Event.Define): Likewise.
+       (SetMethod.GetParameterInfo): Change argument to EmitContext.
+       Pass type array to InternalParameters.
+       (SetIndexerMethod.GetParameterInfo): Likewise.
+       (SetMethod.Define): Pass emitcontext to GetParameterInfo.
+       * delegate.cs (Define): Pass emitcontext to
+       ComputeAndDefineParameterTypes and GetParameterInfo.  Pass type
+       array to InternalParameters.
+       * expression.cs (ParameterReference.DoResolveBase): Pass
+       emitcontext to GetParameterInfo.
+       (ComposedCast.DoResolveAsTypeStep): Remove check on
+       ec.ResolvingTypeTree.
+       * parameter.cs (Parameter.Resolve): Change argument to
+       EmitContext.  Use ResolveAsTypeTerminal.
+       (Parameter.GetSignature): Change argument to EmitContext.
+       (Parameters.ComputeSignature): Likewise.
+       (Parameters.ComputeParameterTypes): Likewise.
+       (Parameters.GetParameterInfo): Likewise.
+       (Parameters.ComputeAndDefineParameterTypes): Likewise.
+       Re-use ComputeParameterTypes.  Set ec.ResolvingTypeTree.
+       * support.cs (InternalParameters..ctor): Remove variant that takes
+       a DeclSpace.
+       * typemanager.cs (system_intptr_expr): New.
+       (InitExpressionTypes): Initialize it.
+
+2004-10-12  Chris Toshok  <toshok@ximian.com>
+
+       * cs-parser.jay: fix location for try_statement and catch_clause.
+
+2004-10-18  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (FieldMember.Define): Don't access the TypeExpr's
+       `Type' directly, but call ResolveType() on it.
+       (MemberBase.DoDefine): Likewise.
+
+       * expression.cs (New.DoResolve): Don't access the TypeExpr's
+       `Type' directly, but call ResolveType() on it.
+       (ComposedCast.DoResolveAsTypeStep): Likewise.
+
+       * statement.cs (LocalInfo.Resolve): Don't access the TypeExpr's
+       `Type' directly, but call ResolveType() on it.
+
+2004-10-17  John Luke  <john.luke@gmail.com>
+
+       * class.cs (Operator.GetSignatureForError): use CSharpName
+
+       * parameter.cs (Parameter.GetSignatureForError): Returns
+       correct name even if was not defined.
+
+2004-10-13  Raja R Harinath  <rharinath@novell.com>
+
+       Fix #65816.
+       * class.cs (TypeContainer.EmitContext): New property.
+       (DefineNestedTypes): Create an emitcontext for each part.
+       (MethodCore.DoDefineParameters): Use container's emitcontext.
+       Pass type array to InternalParameters.
+       (MemberBase.DoDefine): Use container's emitcontext.
+       (FieldMember.Define): Likewise.
+       (Event.Define): Likewise.
+       (SetMethod.GetParameterInfo): Change argument to EmitContext.
+       Pass type array to InternalParameters.
+       (SetIndexerMethod.GetParameterInfo): Likewise.
+       (SetMethod.Define): Pass emitcontext to GetParameterInfo.
+       * delegate.cs (Define): Pass emitcontext to
+       ComputeAndDefineParameterTypes and GetParameterInfo.  Pass type
+       array to InternalParameters.
+       * expression.cs (ParameterReference.DoResolveBase): Pass
+       emitcontext to GetParameterInfo.
+       (ComposedCast.DoResolveAsTypeStep): Remove check on
+       ec.ResolvingTypeTree.
+       * parameter.cs (Parameter.Resolve): Change argument to
+       EmitContext.  Use ResolveAsTypeTerminal.
+       (Parameter.GetSignature): Change argument to EmitContext.
+       (Parameters.ComputeSignature): Likewise.
+       (Parameters.ComputeParameterTypes): Likewise.
+       (Parameters.GetParameterInfo): Likewise.
+       (Parameters.ComputeAndDefineParameterTypes): Likewise.
+       Re-use ComputeParameterTypes.  Set ec.ResolvingTypeTree.
+       * support.cs (InternalParameters..ctor): Remove variant that takes
+       a DeclSpace.
+       * typemanager.cs (system_intptr_expr): New.
+       (InitExpressionTypes): Initialize it.
+
+2004-10-12  Chris Toshok  <toshok@ximian.com>
+
+       * cs-parser.jay: fix location for try_statement and catch_clause.
+
+2004-10-07  Raja R Harinath  <rharinath@novell.com>
+
+       More DeclSpace.ResolveType avoidance.
+       * decl.cs (MemberCore.InUnsafe): New property.
+       * class.cs (MemberBase.DoDefine): Use ResolveAsTypeTerminal 
+       with newly created EmitContext.
+       (FieldMember.Define): Likewise.
+       * delegate.cs (Delegate.Define): Likewise.
+       * ecore.cs (SimpleName.ResolveAsTypeStep): Lookup with alias
+       only if normal name-lookup fails.
+       (TypeExpr.DoResolve): Enable error-checking.
+       * expression.cs (ArrayCreation.DoResolve): Use ResolveAsTypeTerminal.
+       (SizeOf.DoResolve): Likewise.
+       (ComposedCast.DoResolveAsTypeStep): Likewise.
+       (StackAlloc.DoResolve): Likewise.
+       * statement.cs (Block.Flags): Add new flag 'Unsafe'.
+       (Block.Unsafe): New property.
+       (Block.EmitMeta): Set ec.InUnsafe as appropriate.
+       (Unsafe): Set 'unsafe' flag of contained block.
+       (LocalInfo.Resolve): Use ResolveAsTypeTerminal.
+       (Fixed.Resolve): Likewise.
+       (Catch.Resolve): Likewise.
+       (Using.ResolveLocalVariableDecls): Likewise.
+       (Foreach.Resolve): Likewise.
+
+2004-10-05  John Luke <john.luke@gmail.com>
+
+       * cs-parser.jay: add location to error CS0175
+
+2004-10-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (Expression.Constantity): Add support for turning null
+       into a constant.
+
+       * const.cs (Const.Define): Allow constants to be reference types
+       as long as the value is Null.
+
+2004-10-04  Juraj Skripsky  <js@hotfeet.ch>
+
+       * namespace.cs (NamespaceEntry.Using): No matter which warning
+       level is set, check if this namespace name has already been added.
+
+2004-10-03 Ben Maurer  <bmaurer@ximian.com>
+
+       * expression.cs: reftype [!=]= null should always use br[true,false].
+       # 67410
+
+2004-10-03  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix #67108
+       * attribute.cs: Enum conversion moved to 
+       GetAttributeArgumentExpression to be applied to the all
+       expressions.
+
+2004-10-01  Raja R Harinath  <rharinath@novell.com>
+
+       Fix #65833, test-300.cs, cs0122-5.cs, cs0122-6.cs.
+       * class.c (TypeContainer.DefineType): Flag error if
+       base types aren't accessible due to access permissions.
+       * decl.cs (DeclSpace.ResolveType): Move logic to
+       Expression.ResolveAsTypeTerminal.
+       (DeclSpace.ResolveTypeExpr): Thin layer over
+       Expression.ResolveAsTypeTerminal.
+       (DeclSpace.CheckAccessLevel, DeclSpace.FamilyAccess):
+       Refactor code into NestedAccess.  Use it.
+       (DeclSpace.NestedAccess): New.
+       * ecore.cs (Expression.ResolveAsTypeTerminal): Add new
+       argument to silence errors.  Check access permissions.
+       (TypeExpr.DoResolve, TypeExpr.ResolveType): Update.
+       * expression.cs (ProbeExpr.DoResolve): Use ResolveAsTypeTerminal.
+       (Cast.DoResolve): Likewise.
+       (New.DoResolve): Likewise.
+       (InvocationOrCast.DoResolve,ResolveStatement): Likewise.
+       (TypeOf.DoResolve): Likewise.
+
+       * expression.cs (Invocation.BetterConversion): Return the Type of
+       the better conversion.  Implement section 14.4.2.3 more faithfully.
+       (Invocation.BetterFunction): Make boolean.  Make correspondence to
+       section 14.4.2.2 explicit.
+       (Invocation.OverloadResolve): Update.
+       (Invocation): Remove is_base field.
+       (Invocation.DoResolve): Don't use is_base.  Use mg.IsBase.
+       (Invocation.Emit): Likewise.
+
+2004-09-24  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Reverted 642 warning fix.
+
+2004-09-23  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #66615
+       * decl.cs (FindMemberWithSameName): Indexer can have more than
+       1 argument.
+
+2004-09-23  Marek Safar  <marek.safar@seznam.cz>
+
+       * expression.cs (LocalVariableReference.DoResolveLValue):
+       Do not report warning 219 for out values.
+       (EmptyExpression.Null): New member to avoid extra allocations.
+
+2004-09-23  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Fix wrong warning 642 report.
+
+       * cs-tokenizer.cs (CheckNextToken): New helper;
+       Inspect next character if is same as expected.
+
+2004-09-23  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs (Convert.ImplicitReferenceConversion): Some code cleanup.
+       (Convert.ImplicitReferenceConversionExists): Likewise.
+
+2004-11-09  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile (DISTFILES): Comment out a few missing files.
+
+2004-10-29  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile (bootstrap_libs,bootstrap_libfiles): New.
+       (bootstrap-libs): New target.  Invokes the net_2_0_bootstrap profile.
+       (gmcs.exe): Invoke bootstrap-libs.
+       (clean-local): Clean the net_2_0_bootstrap profile too.
+       (PROGRAM_INSTALL_DIR): New.
+       (install-local): Use it.
+
+2004-10-13  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (TypeManager.InflatedConstraints): New nested class.
+       (TypeParameter.DefineType): If we're a method type parameter and
+       that method is overriding something, "inflate" its constraints.
+
+2004-10-12  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (MemberAccess.DoResolve): If we're a SimpleName
+       and have type arguments, create and resolve a ConstructedType.
+
+2004-10-12  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCache.FindMemberToOverride): Use
+       TypeManager.IsEqual() to compare the parameters and Type.Equals()
+       to compare the invocationType.
+
+       * typemanager.cs (TypeManager.IsEqual): Added support for arrays.
+       When comparing two type parameters, only do the signature-only
+       comparision for method type parameters.
+
+2004-10-11  Martin Baulig  <martin@ximian.com>
+
+       * report.cs: Don't make --fatal abort on warnings, we have
+       -warnaserror for that.
+
+2004-10-11  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs
+       (TypeManager.IsEqualGenericType): Removed, use IsEqual() instead.
+       (TypeManager.IsEqual): Call ourself recursively instead of using
+       Type.IsEqual(). 
+
+2004-10-11  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.DefineType): Only call TypeParameter.Define()
+       on our own type parameters, not on the ones we inherit from a containing
+       class.
+
+       * expression.cs (Invocation.InferType): Use `==', not `Equals()' for
+       the comparision.
+
+       * generic.cs (TypeParameter.Define): We may only be called once.
+
+       * pending.cs (Pending.InterfaceMethod): Call TypeManager.Real_IsEqual()
+       instead of TypeManager.IsEqual().
+
+2004-09-28  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs
+       (GenericConstraints.EffectiveBaseClass): New public property.
+       (TypeParameter.GenericConstraints): New public property.
+       (ConstructedType.CheckConstraints): Improved.
+
+       * convert.cs (Convert.TypeParam_EffectiveBaseType): New private method.
+       (Convert.TypeParameterConversion): New private method; use this in
+       ImplicitReferenceConversion() and ImplicitReferenceConversionExists()
+       for all conversions related to type parameters.
+
+2004-09-24  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs (Convert.ImplicitReferenceConversion): Added implicit
+       type parameter conversions for type parameters which are known to
+       be reference types.
+
+2004-09-24  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (GenericConstraints): Added `IsReferenceType' and
+       `IsValueType' properties.
+
+       * support.cs (ReflectionConstraints): Use
+       Type.GetGenericParameterConstraints() instead of the old hack.
+
+2004-09-24  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (GenericConstraints): Moved here and made it an
+       abstract class.
+
+       * support.cs (GenericConstraints): Moved to generic.cs.
+
+2004-09-24  Martin Baulig  <martin@ximian.com>
+
+       * support.cs
+       (ReflectionConstraints): Un-nested this class and made it public.
+
+       * typemanager.cs
+       (TypeManager.GetTypeParameterConstraints): New public method.
+       (TypeManager.HasConstructorConstraint): Use the attributes.
+
+2004-09-24  Martin Baulig  <martin@ximian.com>
+
+       * support.cs (GenericConstraints): Replaced `HasConstructor',
+       `IsReferenceType' and `IsValueType' with `Attributes'.
+       (ReflectionParameters.ReflectionConstraints): Removed the Create()
+       method and made the .ctor public.
+
+       * generic.cs (Constraints.Attributes): New public property.
+       (Constraints): Renamed `HasConstructor' -> `HasConstructorConstraint',
+       `IsReferenceType' -> `HasReferenceTypeConstraint' and
+       `IsValueType' -> `HasValueTypeConstraint'.
+
+2004-09-23  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (Constraints): Reflect latest runtime changes.
+
+2004-09-23  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs (Convert.ImplicitReferenceConversion): Some code cleanup.
+       (Convert.ImplicitReferenceConversionExists): Likewise.
+
+2004-09-23  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (Operator.Define): Add error 448 and 559 report.
+        
+2004-09-22  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (MemberBase.IsTypePermitted): New protected
+       method for checking error CS0610.
+
+2004-09-22  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (TypeContainer.HasExplicitLayout): New property
+       Returns whether container has StructLayout attribute set Explicit.
+       (FieldMember): New abstract class for consts and fields.
+       (FieldMember.ApplyAttributeBuilder): Add error 636 and 637 report.
+       (Field): Reuse FieldMember.
+
+       * const.cs (Const): Reuse FieldMember.
+
+       * rootcontext.cs: EmitConstants call moved to class.
+
+2004-09-22  Martin Baulig  <martin@ximian.com>
+
+       Marek and me just fixed one of our oldest bugs: #28562 :-)
+
+       * ecore.cs (EnumConstant.GetValueAsEnumType): New public method.
+
+       * attribute.cs (Attribute.GetAttributeArgumentExpression): If
+       we're an EnumConstant, just return that.
+       (Attribute.Resolve): GetAttributeArgumentExpression() may give us
+       an EnumConstant.  In this case, we need to use GetValueAsEnumType()
+       to get the value which'll actually be written into the attribute.
+       However, we have to use GetValue() to access the attribute's value
+       in the compiler.        
+
+2004-09-22  Marek Safar  <marek.safar@seznam.cz>
+
+       * constant.cs (Constant.IsNegative): New abstract property
+       IsNegative.
+
+       * expression.cs (ArrayAccess.DoResolve): Add warning 251.
+       (StackAlloc.DoResolve): Reused IsNegative.
+
+2004-09-22  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.LookupGenericTypeContainer): New
+       public method; like LookupTypeContainer, but also works for
+       generic instances.
+
+       * report.cs (Report.SymbolRelatedToPreviousError): Use
+       TypeManager.LookupGenericTypeContainer().       
+
+2004-09-22  Martin Baulig  <martin@ximian.com>
+
+       Thanks to Peter Sestoft for this bug report.
+
+       * expression.cs (Conditional): If both the `trueExpr' and the
+       `falseExpr' is a NullLiteral, return a NullLiteral.
+
+2004-09-22  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Foreach.EmitCollectionForeach): If we're in an
+       iterator, use `enumerator.EmitThis()' instead of `ec.EmitThis()'
+       for the "get_Current" call.
+
+2004-09-21  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs (Convert.ImplicitReferenceConversion): When
+       converting to an interface type, first check whether we're
+       converting from a reference type.
+
+2004-09-14  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCore.Emit): Always call VerifyObsoleteAttribute().
+
+2004-09-14  Marek Safar  <marek.safar@seznam.cz>
+
+       Fixed bug #61902
+       * codegen.cs (TestObsoleteMethodUsage): Trace when method is
+       called and is obsolete then this member suppress message
+       when call is inside next [Obsolete] method or type.
+
+       * expression.cs: Use TestObsoleteMethodUsage member.
+
+2004-09-14  Martin Baulig  <martin@ximian.com>
+
+       * genericparser.cs: Removed.
+
+2004-09-13  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (MethodCore.CheckBase): Fix bug #65757.
+
+2004-09-12  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs (Attribute.Resolve): Add error 653 report.
+
+       * class.cs (Class.ApplyAttributeBuilder): Add error 641
+       report.
+       (Method.ApplyAttributeBuilder): Add error 685 report.
+       (Operator.Define): Add error 564 report.
+
+       * cs-tokenizer.cs (handle_hex): Add error 1013 report.
+
+       * expression.cs (Invocation.DoResolve): Add error
+       245 and 250 report.
+
+       * parameter.cs (Parameter.ApplyAttributeBuilder): Add
+       error 674 report.
+
+2004-09-11  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (ConstructorInitializer.Resolve):
+       Wrong error number (515->516).
+
+2004-09-11  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (Indexer.Define): Add error 631 report.
+
+2004-09-11  Marek Safar  <marek.safar@seznam.cz>
+
+       * ecore.cs (Error_NegativeArrayIndex): Fix 248 error.
+
+2004-09-11  Marek Safar  <marek.safar@seznam.cz>
+
+       * expression.cs (Probe.DoResolve): Add error CS0241 report.
+
+2004-09-10  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Added error CS0241 report.
+
+2004-09-10  Raja R Harinath  <rharinath@novell.com>
+
+       * cs-parser.jay (fixed_statement): Introduce a scope for the
+       declaration in the 'fixed' statement.
+
+2004-09-09  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Added CS0230 error report.
+
+2004-09-09  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Added errors CS0231 and CS0257 report.
+
+2004-09-09  Marek Safar  <marek.safar@seznam.cz>
+
+       * expression.cs (Argument.Resolve): Added error CS0192 and
+       CS0199 report.
+
+2004-09-09  Marek Safar  <marek.safar@seznam.cz>
+
+       C# 2.0 #pragma warning feature
+
+       * cs-tokenizer.cs (PreProcessPragma): New method; 
+       Handles #pragma directive.
+
+       * report.cs (WarningRegions): New class; Support
+       class for #pragma warning directive. It tests whether
+       warning is enabled for a given line.
+
+2004-09-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * const.cs: Add more descriptive error report, tahnks to
+       Sebastien. 
+
+2004-09-08  Marek Safar  <marek.safar@seznam.cz>
+
+       * ecore.cs (FieldExpr.DoResolveLValue): Fixed CS0198 report.
+
+2004-09-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Apply patch from Ben: Remove dead code from
+       ArrayCreation, and remove the TurnintoConstant call in const.cs,
+       as that code just threw an exception anwyays.
+
+       * const.cs: Remove the call to the turnintoconstant, for details
+       see bug: #63144
+       
+       * literal.cs: The type of the null-literal is the null type;  So
+       we use a placeholder type (literal.cs:System.Null, defined here)
+       for it.
+
+       * expression.cs (Conditional.DoResolve): Remove some old code that
+       is no longer needed, conversions have been fixed.
+
+       (ArrayCreationExpression.DoResolve): Return false if we fail to
+       resolve the inner expression.
+
+2004-09-07  Raja R Harinath  <rharinath@novell.com>
+
+       Fix test-290.cs.
+       * cs-parser.jay (delegate_declaration): Record a delegate
+       declaration as a type declaration.
+       Reported by Jo Vermeulen <jo@lumumba.luc.ac.be>.
+
+2004-09-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * parameter.cs: Do not crash if the type can not be resolved. 
+
+       * expression.cs: Report errors with unsafe pointers, fixes #64896
+
+2004-09-06 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: Pointer arith always needs to do a conv.i
+       if the operand is a long. fix 65320
+
+2004-09-04  Marek Safar  <marek.safar@seznam.cz>
+
+       Fixed cs0619-37.cs, cs0619-38.cs
+
+       * enum.cs (GetObsoleteAttribute): Removed.
+
+       * expression.cs (MemberAccess.DoResolve): Test for [Obsolete]
+       on Enum member is double staged. The first is tested member
+       and then enum.
+
+2004-09-04  Marek Safar  <marek.safar@seznam.cz>
+
+       Fixed #56986, #63631, #65231
+
+       * class.cs: (TypeContainer.AddToMemberContainer): New method,
+       adds member to name container.
+       (TypeContainer.AddToTypeContainer): New method, adds type to
+       name container.
+       (AddConstant, AddEnum, AddClassOrStruct, AddDelegate, AddMethod,
+       AddConstructor, AddInterface, AddField, AddProperty, AddEvent,
+       AddOperator): Simplified by reusing AddToMemberContainer.
+       (TypeContainer.UserDefinedStaticConstructor): Changed to property
+       instead of field.
+       (Method.CheckForDuplications): Fixed implementation to test all
+       possibilities.
+       (MemberBase): Detection whether member is explicit interface
+       implementation is now in constructor.
+       (MemberBase.UpdateMemberName): Handles IndexerName.
+       (Accessor): Changed to keep also location information.
+       (AbstractPropertyEventMethod): Is derived from MemberCore.
+       (AbstractPropertyEventMethod.IsDummy): Says whether accessor
+       will be emited or not.
+       (PropertyBase.AreAccessorsDuplicateImplementation):
+       Tests whether accessors are not in collision with some method.
+       (Operator): Is derived from MethodCore to simplify common
+       operations.
+
+       * decl.cs (Flags.TestMethodDuplication): Test for duplication
+       must be performed.
+       (DeclSpace.AddToContainer): Adds the member to defined_names
+       table. It tests for duplications and enclosing name conflicts.
+
+       * enum.cs (EnumMember): Clean up to reuse the base structures
+
+2004-09-03  Martin Baulig  <martin@ximian.com>
+
+       Merged latest changes into gmcs.  Please keep this comment in
+       here, it makes it easier for me to see what changed in MCS since
+       the last time I merged.
+
+2004-09-03  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.DefineDefaultConstructor): Put this back
+       into TypeContainer, to make partial classes work again.
+
+2004-09-03  Martin Baulig  <martin@ximian.com>
+
+       * rootcontext.cs (RootContext.V2): Removed.
+
+2004-03-23  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.OverloadResolve): Added `bool
+       may_fail' argument and use it instead of the Location.IsNull() hack.
+
+2004-09-09  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay (namespace_declaration): Fixed CS0134 reporting.
+
+2004-09-09  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (TypeParameter.DefineType): Added support for
+       explicit interface methods.
+
+2004-09-09  Martin Baulig  <martin@ximian.com>
+
+       * README.Changes: New document.  Started to list important changes
+       between MCS and GMCS here.
+
+2004-09-08  Martin Baulig  <martin@ximian.com>
+
+       * class.cs
+       (TypeContainer.CheckRecursiveDefinition): New protected method.
+       (TypeContainer.DefineType): Move the CS0146 check into
+       CheckRecursiveDefinition().     
+
+2004-09-06  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.CheckConstraints): Allow builtin
+       types for the constructor constraint.
+
+2004-09-03  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.DefineDefaultConstructor): Put this back
+       into TypeContainer, to make partial classes work again.
+
+2004-09-03  Martin Baulig  <martin@ximian.com>
+
+       * rootcontext.cs (RootContext.V2): Removed.
+
+2004-03-23  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.OverloadResolve): Added `bool
+       may_fail' argument and use it instead of the Location.IsNull() hack.
+
+2004-09-03  Martin Baulig  <martin@ximian.com>
+
+       Merged latest changes into gmcs.  Please keep this comment in
+       here, it makes it easier for me to see what changed in MCS since
+       the last time I merged.
+
+2004-09-03  Raja R Harinath  <rharinath@novell.com>
+
+       Fix #61128.
+       * expression.cs (BetterConversion): Don't allow either conversion 
+       to be null.  Remove redundant implicit conversion test when 'q ==
+       null' -- when this function is invoked, we already know that the
+       implicit conversion exists.
+       (BetterFunction): Assume that 'best' is non-null.  Remove
+       redundant reimplementation of IsApplicable when 'best' is null.
+       (IsParamsMethodApplicable, IsApplicable): Add new parameter for
+       number of arguments.
+       (IsAncestralType): Extract from OverloadResolve.
+       (OverloadResolve): Make robust to the MethodGroupExpr being
+       unsorted.  Implement all the logic of Section 14.5.5.1, and
+       support overloading of methods from multiple applicable types.
+       Clean up logic somewhat.  Don't pass null methods to BetterFunction.
+
+       * report.cs (SymbolRelatedToPreviousError): Cleanup output.
+       (RealError, Warning): Append type of report to related symbol.
+
+2004-09-03  Marek Safar  <marek.safar@seznam.cz>
+
+       * enum.cs: Fixed CLS-Compliance checks for enum members.
+       Error tests cs3008-8.cs, cs3014-8.cs
+
+2004-09-02  Marek Safar  <marek.safar@seznam.cz>
+
+       Fixed bug #62342, #63102
+       * class.cs: ImplementIndexer uses member.IsExplicitImpl
+       like ImplementMethod.
+
+2004-09-02  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs (Attribute.GetAttributeArgumentExpression):
+       Fixed bug #65170.
+
+2004-09-02  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Using.EmitLocalVariableDeclFinally): Use
+       TypeManager.GetArgumentTypes() rather than calling GetParameters()
+       on the MethodBase.
+
+2004-09-01  Marek Safar  <marek.safar@seznam.cz>
+
+       C# 2.0 Static classes implemented
+
+       * class.cs (TypeContainer): instance_constructors,
+       initialized_fields, initialized_static_fields,
+       default_constructor, base_inteface_types are protected to be
+       accessible from StaticClass.
+       (TypeContainer.DefineDefaultConstructor): New virtual method
+       for custom default constructor generating
+       (StaticClass): New class to handle "Static classes" feature.
+
+       * cs-parser.jay: Handle static keyword on class like instance
+       of StaticClass.
+
+       * driver.cs: Added "/langversion" command line switch with two
+       options (iso-1, default).
+
+2004-08-31  Marek Safar  <marek.safar@seznam.cz>
+
+       * ecore.cs (FieldExpr.Resolve): Fixed bug #64689.
+
+2004-08-31  Miguel de Icaza  <miguel@ximian.com>
+
+       * delegate.cs: Style.
+
+2004-08-31 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * delegate.cs: Add seperate instance expr field for miguel.
+
+2004-08-29 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * PointerArithmetic (Resolve): make sure we are not doing
+       pointer arith on void*. Also, make sure we are resolved
+       by not setting eclass until resolve.
+
+       All callers: Make sure that PointerArithmetic gets resolved.
+
+2004-08-29 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * ArrayCreation (LookupType): If the type does not resolve 
+       to an array, give an error.
+
+2004-08-27  Marek Safar  <marek.safar@seznam.cz>
+
+       * statement.cs (Try.Resolve): Fixed bug #64222
+
+2004-08-27  Martin Baulig  <martin@ximian.com>
+
+       * class.cs
+       (TC.OperatorArrayList.OperatorEntry.CheckPairedOperators): Don't
+       crash here.     
+
+2004-08-26  Marek Safar  <marek.safar@seznam.cz>
+
+       * ecore.cs (Constantify): Get underlying type via
+       System.Enum.GetUnderlyingType to avoid StackOverflow on the
+       Windows in special cases.
+
+2004-08-26  Marek Safar  <marek.safar@seznam.cz>
+
+       * typemanager.cs (GetAddMethod): Used GetAddMethod (true)
+       for obtaining also private methods.
+       (GetRemoveMethod): Used GetRemoveMethod (true)
+       for obtaining also private methods.
+
+2004-09-02  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Using.EmitLocalVariableDeclFinally): Use
+       TypeManager.GetArgumentTypes() rather than calling GetParameters()
+       on the MethodBase.
+
+2004-08-27  Martin Baulig  <martin@ximian.com>
+
+       * class.cs
+       (TC.OperatorArrayList.OperatorEntry.CheckPairedOperators): Don't
+       crash here.     
+
+2004-08-25  Martin Baulig  <martin@ximian.com>
+
+       * support.cs (ReflectionParameters..ctor): If this is a generic
+       method, retrieve and store its type parameters.
+       (InternalParameters..ctor): Added `TypeParameter[]' argument.
+       (ReflectionParameters.GenericConstraints): The argument specifies
+       the type parameter, not the method parameter.
+       (InternalParameters.GenericConstraints): Likewise.
+
+       * generic.cs (TypeParameter.DefineType): Correctly handle
+       constraints wrt. generic methods in interfaces and their
+       implementations.        
+
+2004-08-24  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (TypeParameter.IsSubclassOf): New public method.
+       (Constraints.IsSubclassOf): New internal method.
+
+       * typemanager.cs (TypeManager.FindMembers): Added special support
+       for GenericTypeParameterBuilder's.      
+       (TypeManager.IsSubclassOf, IsFamilyAccessible): Added support for
+       type parameters.
+
+2004-08-24  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs
+       (TypeManager.IsSubclassOf): Renamed to IsFamilyAccessible; use
+       this for accessibility checks.
+       (TypeManager.IsSubclassOrNestedChildOf): Renamed to
+       IsNestedFamilyAccessible.
+       (TypeManager.IsSubclassOf): New method, do what the name actually
+       says.   
+
+2004-08-24  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (MemberAccess.DoResolve): When resolving ourselves
+       as a SimpleName, include the generic arity.
+
+2004-08-24  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Method.Define): Set MethodAttributes.SpecialName and
+       MethodAttributes.HideBySig for operators.
+
+2004-08-23  Martin Baulig  <martin@ximian.com>
+
+       Back to the old error reporting system :-)
+
+       * report.cs (Message): Removed.
+       (Report.MessageData, ErrorData, WarningData): Removed.
+       (Report.Error, Warning): Back to the old system.
+
+2004-08-23  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (IMemberContainer.Parent): Renamed to ParentContainer.
+
+       * class.cs (TypeContainer.ParentContainer): New public virtual
+       method; replaces the explicit interface implementation.
+       (ClassPart.ParentContainer): Override.
+
+2004-08-23  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Switch): Added support for constant switches; see
+       #59428 or test-285.cs.
+
+2004-08-22  Marek Safar  <marek.safar@seznam.cz>
+
+       Fixed bug #62740.
+       * statement.cs (GetEnumeratorFilter): Removed useless
+       logic because C# specs is strict. GetEnumerator must be
+       public.
+
+2004-08-22  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowBranching.UsageVector.MergeChild): If we're
+       a switch and may break, reset the barrier.  Fixes #59867.
+
+2004-08-22  Marek Safar  <marek.safar@seznam.cz>
+
+       CLS-Compliance speed up (~5% for corlib)
+
+       * attribute.cs (AttributeTester.VerifyTopLevelNameClsCompliance):
+       New method. Tests container for CLS-Compliant names
+
+       * class.cs (TypeContainer.VerifyClsName): New method.
+       Checks whether container name is CLS Compliant.
+       (Constructor): Implements IMethodData.
+
+       * decl.cs (MemberCache.GetPublicMembers ): New method. Builds
+       low-case table for CLS Compliance test.
+       (MemberCache.VerifyClsParameterConflict): New method.
+       Checks method parameters for CS3006 error.
+
+       * enum.cs (EnumMember): Is derived from MemberCore.
+       (Enum.VerifyClsName): Optimized for better performance.
+
+2004-08-06  Marek Safar  <marek.safar@seznam.cz>
+
+       * report.cs: Renamed Error_T to Error and changed all
+       references.
+
+2004-08-06  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (TypeContainer.IndexerArrayList): New inner class
+       container for indexers.
+       (TypeContainer.DefaultIndexerName): New constant for default
+       indexer name. Replaced all "Item" with this constant.
+       (TypeContainer.DefineIndexers): Moved to IndexerArrayList class.
+
+       * typemanager.cs (TypeManager.default_member_ctor): Cache here
+       DefaultMemberAttribute constructor.
+
+2004-08-05  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowBranching.UsageVector.MergeJumpOrigins):
+       Fix bug #59429.
+
+2004-08-05  Marek Safar  <marek.safar@seznam.cz>
+
+       * mcs.exe.sources: $(EXTRA_SOURCES) are now here to avoid
+       multi platforms problem.
+
+       * compiler.csproj: Included shared files.
+
+2004-08-04  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug 60333, 55971 in the more general way
+       * attribute.cs (Attribute.GetAttributeArgumentExpression):
+       Added arg_type argument for constant conversion.
+       (Attribute.Resolve): Reuse GetAttributeArgumentExpression.
+
+2004-08-04  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #59760
+       * class.cs (TypeContainer ): New inner classes MethodArrayList, 
+       OperatorArrayList, MethodCoreArrayList for typecontainer
+       containers. Changed class member types to these new types.
+       (MethodArrayList.DefineMembers): Added test for CS0659.
+
+2004-08-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * cfold.cs: Synchronize the folding with the code in expression.cs
+       Binary.DoNumericPromotions for uint operands.
+
+       * attribute.cs: Revert patch from Raja, it introduced a regression
+       while building Blam-1.2.1 (hard to isolate a test case).
+
+2004-08-04  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix for #55382
+       * class.cs:
+       (TypeContainer.Define): Renamed to DefineContainerMembers because of
+       name collision.
+       (MethodCore.parent_method): New member. The method we're overriding
+       if this is an override method.
+       (MethodCore.CheckBase): Moved from Method class and made common.
+       (MethodCore.CheckMethodAgainstBase): Moved from MemberBase and made
+       private.
+       (MethodCore.CheckForDuplications): New abstract method. For custom
+       member duplication search in a container
+       (MethodCore.FindOutParentMethod): New abstract method. Gets parent
+       method and its return type.
+       (Event.conflict_symbol): New member. Symbol with same name in the
+       parent class.
+
+       * decl.cs:
+       (MemberCache.FindMemberWithSameName): New method. The method
+       is looking for conflict with inherited symbols.
+
+2004-08-04  Martin Baulig  <martin@ximian.com>
+
+       * codegen.cs (VariableStorage.EmitLoadAddress): New public method.
+
+       * statement.cs (Foreach.EmitFinally): Make this work for valuetypes.
+
+2004-08-03  Marek Safar  <marek.safar@seznam.cz>
+
+       * report.cs (Message): New enum for better error, warning reference in
+       the code.
+       (MessageData): New inner abstract class. It generally handles printing of
+       error and warning messages.
+       Removed unused Error, Warning, Message methods.
+
+2004-08-03  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix for cs0592-8.cs test
+       * attribute.cs
+       (Attributable.ValidAttributeTargets): Made public.
+       (Attribute.ExplicitTarget): New member for explicit target value.
+       (Attribute.CheckTargets): Now we translate explicit attribute
+       target to Target here.
+
+2004-08-03  Ben Maurer  <bmaurer@ximian.com>
+
+       * ecore.cs (MethodGroupExpr): new IsBase property.
+
+       * expression.cs (BaseAccess): Set IsBase on MethodGroupExpr.
+
+       * delegate.cs (DelegateCreation): store a MethodGroupExpr
+       rather than an instance expr.
+
+       (DelegateCreation.Emit): Use the method group rather than
+       the instance expression. Also, if you have base.Foo as the
+       method for a delegate, make sure to emit ldftn, not ldftnvirt.
+
+       (ResolveMethodGroupExpr): Use the MethodGroupExpr. 
+
+       (NewDelegate.DoResolve): Only check for the existance of Invoke
+       if the method is going to be needed. Use MethodGroupExpr.
+
+       (NewDelegate.Emit): Remove, DelegateCreation implements this.   
+
+       * expression.cs: For pointer arith., make sure to use
+       the size of the type, not the size of the pointer to
+       the type.
+
+2004-08-03  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix for #60722
+       * class.cs (Class): Added error CS0502 test.
+
+2004-08-03  John Luke  <jluke@cfl.rr.com>
+           Raja R Harinath  <rharinath@novell.com>
+
+       Fix for #60997.
+       * attribute.cs (Attribute.complained_before): New flag.
+       (Attribute.ResolveType, Attribute.Resolve),
+       (Attribute.DefinePInvokeMethod): Set it.
+       (Attributes.Search): Pass 'complain' to Attribute.ResolveType.
+       
+2004-08-03  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Binary.ResolveOperator): Don't abort if we can't
+       use a user-defined operator; we still need to do numeric
+       promotions in case one argument is a builtin type and the other
+       one has an implicit conversion to that type.  Fixes #62322.
+
+2004-08-18  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Method.Define): Use the correct method name when
+       creating the MethodBuilder for a generic method.
+
+2004-08-17  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (Constraints): Support type parameter constraints.
+
+2004-08-16  Martin Baulig  <martin@ximian.com>
+
+       * cs-tokenizer.cs (Tokenizer.TypeOfParsing): New public property.
+       (Token.GENERIC_DIMENSION): New token; this is returned if we
+       encounter an unbound generic type in a typeof() expression.
+
+       * cs-parser.jay (opt_type_argument_list): Added GENERIC_DIMENSION;
+       this token is only generated while parsing a typeof() expression.
+       (typeof_expression): Removed the old unbound_type hack.
+
+       * generic.cs (TypeArguments.IsUnbound): New public property.
+
+       * decl.cs (MemberName): Added support for unbound types.
+
+2004-08-14  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs
+       (TypeManager.IsEqualGenericInstance): New static method.
+       (TypeManager.IsSubclassOrNestedChildOf, IsSubclassOf): This is
+       just used to check accessibility, so follow the rules of 26.1.6.        
+
+       * expression.cs (MemberAccess.ResolveAsTypeStep): Return a
+       ConstructedType instead of a TypeExpression if we have type arguments.
+
+       * cs-parser.jay (typeof_expression): Support unbound generic types.
+
+       * ecore.cs (UnboundTypeExpression): New public class.
+
+2004-08-12  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.IsNestedChildOf): Use
+       TypeManager.IsEqual() rather than `=='.
+
+       * decl.cs (DeclSpace.CheckAccessLevel): Use `tb.FullName' for
+       generic instances as well.
+
+2004-08-12  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.InferType): We can only infer method
+       type parameters.  Fixes #62647.
+
+2004-08-11  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.DefineType): Create the TypeBuilder
+       before resolving the base classes.
+
+2004-08-06 Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * Makefile: install .mdb file too.
+
+2004-08-05  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (FieldExpr.DoResolveLValue): If we're resolving a field
+       initializer, the current type is just the TypeBuilder, not the
+       instantiated generic type.
+       (FieldExpr.IsFieldInitializer): New public property.
+
+2004-08-04  Martin Baulig  <martin@ximian.com>
+
+       * codegen.cs (VariableStorage.EmitLoadAddress): New public method.
+
+       * statement.cs (Foreach.EmitFinally): Make this work for valuetypes.
+
+2004-08-03  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodData.Define): If we're an explicit
+       implementation, remove the generic arity from the type name.
+
+2004-08-03  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Binary.ResolveOperator): Don't abort if we can't
+       use a user-defined operator; we still need to do numeric
+       promotions in case one argument is a builtin type and the other
+       one has an implicit conversion to that type.  Fixes #62322.
+
+2004-08-02  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.ifaces): Make this a `Type[]', not a
+       `TypeExpr[]' array.
+       (TypeContainer.GetClassBases): Return the unexpanded list of
+       interfaces; we expand them later.
+       (TypeContainer.DefineType): After creating the TypeBuilder, call
+       TypeManager.ExpandInterfaces() to get an expanded and resolved
+       list of interfaces.
+
+       * ecore.cs (TypeExpr.GetInterfaces): Removed
+
+       * generics.cs (Constraints.InterfaceConstraints): Remove.
+       (TypeParameter.DefineType): Call TypeManager.RegisterBuilder() to
+       register the interface constraints.
+
+       * typemanager.cs
+       (TypeManager.AddUserType): Removed the `ifaces' argument.
+       (TypeManager.AddTypeParameter): Likewise.
+       (TypeManager.AddUserInterface): Removed, was unused.
+       (TypeManager.RegisterBuilder): Take a `Type[]' instead of a
+       `TypeExpr[]' array for the interfaces.
+       (TypeManager.ExpandInterfaces): Call this after the TypeBuilder
+       has been defined, returns a list of the resolved interfaces types.
+       (TypeManager.GetInterfaces): Return a `Type[]', not a `TypeExpr[]'.
+       (TypeManager.GetExplicitInterfaces): Likewise.  
+
+2004-08-02  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.EmitCall): If we're invoking a method
+       on a type parameter, use the new `Constrained' prefix opcode.
+
+2004-08-02  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (LocalInfo.Flags): Added `IsThis'.
+       (LocalInfo.IsThis): New public property.
+       (Block.EmitMeta): Don't create a LocalBuilder for `this'.
+
+2004-08-01  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.GetClassBases): Don't set the default
+       here since we may get called from GetPartialBases().
+       (TypeContainer.DefineType): If GetClassBases() didn't return a
+       parent, use the default one.
+
+2004-07-30  Martin Baulig  <martin@ximian.com>
+
+       * Makefile (EXTRA_SOURCES): List the symbol writer's sources here.
+
+       * class.cs (SourceMethod): New public class, derive from the
+       symbol writer's ISourceMethod.
+       (Method): Use the new symbol writer API.
+
+       * codegen.cs (CodeGen.InitializeSymbolWriter): Take the filename
+       as argument and use the new symbol writer.
+
+       * location.cs
+       (SourceFile): Implement the symbol writer's ISourceFile.
+       (Location.SymbolDocument): Removed.
+       (Location.SourceFile): New public property.
+
+       * symbolwriter.cs: Use the new symbol writer API.
+
+2004-07-30  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile (install-local): Remove.  Functionality moved to
+       executable.make.
+
+2004-07-28  Lluis Sanchez Gual  <lluis@novell.com>
+
+       * Makefile: Install mcs.exe.config file together with mcs.exe.
+       * mcs.exe.config: Added supportedRuntime entry to make sure it runs in the
+       correct runtime version.
+       
+2004-07-25  Martin Baulig  <martin@ximian.com>
+
+       * class.cs
+       (TypeContainer.RegisterOrder): Removed, this was unused.
+       (TypeContainer, interface_order): Removed.
+       (TypeContainer.AddClass, AddStruct, AddInterface): Take a
+       TypeContainer as argument since we can also be called with a
+       `PartialContainer' for a partial class/struct/interface.
+       (TypeContainer.IsInterface): Use `Kind == Kind.Interface' instead
+       of checking whether we're an `Interface' - we could be a
+       `PartialContainer'.
+       (PartialContainer.Register): Override; call
+       AddClass()/AddStruct()/AddInterface() on our parent.
+
+       * cs-parser.jay (interface_member_declaration): Add things to the
+       `current_container', not the `current_class'.
+
+       * rootcontext.cs (RegisterOrder): The overloaded version which
+       takes an `Interface' was unused, removed.
+
+       * typemanager.cs (TypeManager.LookupInterface): Return a
+       `TypeContainer', not an `Interface'.
+       (TypeManager.IsInterfaceType): The `builder_to_declspace' may
+       contain a `PartialContainer' for an interface, so check it's
+       `Kind' to figure out what it is.
+
+2004-07-25  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Class.DefaultTypeAttributes): New public constant.
+       (Struct.DefaultTypeAttributes): Likewise.
+       (Interface.DefaultTypeAttributes): Likewise.
+       (PartialContainer.TypeAttr): Override this and add the
+       DefaultTypeAttributes.
+
+2004-07-25  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.Emit): Removed the `TypeContainer' argument,
+       we can just use the `Parent' field instead.
+
+2004-07-25  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.Emit): Renamed to EmitType().
+
+2004-07-25  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.DefineMembers): Call DefineMembers() on
+       our parts before defining any methods.
+       (TypeContainer.VerifyImplements): Make this virtual.
+       (ClassPart.VerifyImplements): Override and call VerifyImplements()
+       on our PartialContainer.
+
+2004-07-25  Martin Baulig  <martin@ximian.com>
+
+       * iterators.cs (Iterator.Define): Renamed to DefineIterator().
+
+       * decl.cs (DeclSpace.Define): Removed the `TypeContainer'
+       argument, we can just use the `Parent' field instead.
+
+       * class.cs
+       (MemberBase.CheckBase): Removed the `TypeContainer' argument.   
+       (MemberBase.DoDefine): Likewise.
+
+2004-07-24  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCore.Parent): New public field.
+       (DeclSpace.Parent): Moved to MemberCore.
+
+       * class.cs (MethodCore.ds): Removed; use `Parent' instead.
+       (MemberBase.ctor): Added TypeContainer argument, pass it to our
+       parent's .ctor.
+       (FieldBase, Field, Operator): Likewise.
+       (EventProperty.ctor): Take a TypeContainer instead of a DeclSpace.
+       (EventField, Event): Likewise.
+
+2004-07-23  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (PartialContainer): New public class.
+       (ClassPart): New public class.
+       (TypeContainer): Added support for partial classes.
+       (TypeContainer.GetClassBases): Splitted some of the functionality
+       out into GetNormalBases() and GetPartialBases().
+
+       * cs-tokenizer.cs (Token.PARTIAL): New token.
+       (Tokenizer.consume_identifier): Added some hacks to recognize
+       `partial', but only if it's immediately followed by `class',
+       `struct' or `interface'.
+
+       * cs-parser.jay: Added support for partial clases.
+
+2004-07-23  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodCore.ds): Made this a `TypeContainer' instead of
+       a `DeclSpace' and also made it readonly.
+       (MethodCore.ctor): Take a TypeContainer instead of a DeclSpace.
+       (Method.ctor, Constructor.ctor, Destruktor.ctor): Likewise.
+       (PropertyBase.ctor, Property.ctor, Indexer.ctor): Likewise.
+
+       * cs-parser.jay: Pass the `current_class', not the
+       `current_container' (at the moment, this is still the same thing)
+       to a new Method, Property, Event, Indexer or Constructor.
+
+2004-07-23  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay (CSharpParser): Added a new `current_class' field
+       and removed the `current_interface' one.
+       (struct_declaration, class_declaration, interface_declaration):
+       Set `current_class' to the newly created class/struct/interface;
+       set their `Bases' and call Register() before parsing their body.
+
+2004-07-23  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Kind): New public enum.
+       (TypeContainer): Made this class abstract.
+       (TypeContainer.Kind): New public readonly field.
+       (TypeContainer.CheckDef): New public method; moved here from
+       cs-parser.jay.
+       (TypeContainer.Register): New public abstract method.
+       (TypeContainer.GetPendingImplementations): New public abstract
+       method.
+       (TypeContainer.GetClassBases): Removed the `is_class' and
+       `is_iface' parameters.
+       (TypeContainer.DefineNestedTypes): Formerly known as
+       DoDefineType().
+       (ClassOrStruct): Made this class abstract.
+
+       * tree.cs (RootTypes): New public type. 
+
+2004-07-20  Martin Baulig  <martin@ximian.com>
+
+       * tree.cs (Tree.RecordNamespace): Removed.
+       (Tree.Namespaces): Removed.
+
+       * rootcontext.cs (RootContext.IsNamespace): Removed.
+
+       * cs-parser.jay (namespace_declaration): Just create a new
+       NamespaceEntry here.
+
+2004-07-21  Lluis Sanchez Gual  <lluis@novell.com>
+
+       * Makefile: Install gmcs.exe.config file together with gmcs.exe.
+       * gmcs.exe.config: Renamed from mcs.exe.config. Added supportedRuntime
+       entry to make sure it runs in the correct runtime version.
+       
+2004-07-18  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.CheckConstraints): Improved
+       constraints checking.
+
+2004-07-18  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.BetterMethod): Call
+       TypeManager.TypeToCoreType() on all types and removed my previous
+       hack; we're already doig the right thing here.
+
+2004-07-17  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberName.MakeName): Create the "class`1" names here.
+
+2004-07-16  Martin Baulig  <martin@ximian.com>
+
+       * iterators.cs: Added generics support.
+
+2004-07-16  Martin Baulig  <martin@ximian.com>
+
+       * iterators.cs: Rewrote this.  We're now using one single Proxy
+       class for both the IEnumerable and the IEnumerator interface and
+       `Iterator' derives from Class so we can use the high-level API.
+
+       * class.cs (TypeContainer.AddIterator): New method.
+       (TypeContainer.DoDefineType): New protected virtual method, which
+       is called from DefineType().
+       (TypeContainer.DoDefineMembers): Call DefineType() and
+       DefineMembers() on all our iterators.
+       (TypeContainer.Emit): Call Emit() on all our iterators.
+       (TypeContainer.CloseType): Call CloseType() on all our iterators.
+
+       * codegen.cs (EmitContext.CurrentIterator): New public field.
+
+2004-07-15  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs
+       (TypeManager.not_supported_exception_type): New type.   
+
+2004-07-14  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs
+       (TypeManager.generic_ienumerable_type): New type.
+       (TypeManager.generic_ienumerator_type): New type.
+
+       * rootcontext.cs
+       (RootContext.interfaces_first_stage): Added
+       "System.Collections.Generic.IEnumerator`1" and
+       "System.Collections.Generic.IEnumerable`1".     
+
+2004-07-14  Martin Baulig  <martin@ximian.com>
+
+       * iterators.cs: Use real error numbers.
+
+2004-07-14  Martin Baulig  <martin@ximian.com>
+
+       * iterator.cs (IteratorHandle.IsIEnumerable): The spec explicitly
+       requires this to be a System.Collection.IEnumerable and not a
+       class implementing that interface.
+       (IteratorHandle.IsIEnumerator): Likewise, for IEnumerator.      
+
+2004-07-13  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs: Fixed previous fix, it broke some error tests.
+
+2004-07-12  Martin Baulig  <martin@ximian.com>
+
+       * enum.cs (Enum.Define): Call Emit() to emit the attributes.
+       Fixes #61293.
+
+2004-07-14  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs, expression.cs, generic.cs: Use a backqoute (`) and not
+       an exclamation mark (!) for the generic arity to reflect the
+       latest spec changes; ie. use "System.Collections.Generic.IList`1".
+
+2004-07-13  Martin Baulig  <martin@ximian.com>
+
+       * cs-tokenizer.cs (Tokenizer.parse_less_than): Allow array rank
+       specifiers being part of a type argument.
+
+2004-07-13  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (MemberAccess.ResolveAsTypeStep): Use the full `!'
+       name for generic types.
+
+2004-07-13  Martin Baulig  <martin@ximian.com>
+
+       * assign.cs (Assign.DoResolve): Moved the CS0131 check up a little
+       bit to fix #60119.
+
+2004-07-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs (LocalTemporary): Add new argument: is_address,If
+       `is_address' is true, then the value that we store is the address
+       to the real value, and not the value itself.
+       
+       * ecore.cs (PropertyExpr): use the new local temporary
+       stuff to allow us to handle X.Y += z (where X is a struct)
+
+2004-07-08  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Lock.Resolve): Set ec.NeedReturnLabel() if we do
+       not always return, just like we're doing in Using.Resolve().
+
+2004-07-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay (fixed_statement): flag this as Pinned.
+
+2004-07-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (TypeManager): Removed MakePinned method, this
+       mechanism is replaced with the .NET 2.x compatible mechanism of
+       calling `ILGenerator.DeclareLocal (Type t, bool pinned)'.
+
+       * statement.cs (LocalInfo): Remove MakePinned, add Pinned property 
+       Rename `Fixed' to `Pinned' as a flag, to distinguish from the
+       `IsFixed' property which has a different meaning.
+
+2004-07-02  Raja R Harinath  <rharinath@novell.com>
+
+       * ecore.cs (DoSimpleNameResolve): Expand CS0038 check to all names
+       visible from inside a nested class, not just the names of the
+       immediately enclosing class.
+       Fix for bug #60730.
+
+2004-06-24  Raja R Harinath  <rharinath@novell.com>
+
+       * expression.cs (BetterConversion): Remove buggy special-case
+       handling of "implicit constant expression conversions".  At this
+       point, we already know that the conversion is possible -- we're
+       only checking to see which is better.
+
+2004-06-24  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Added error CS0210 test.
+
+2004-06-24  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Added error CS0134 test.
+
+2004-06-24  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #52507
+       * cs-parser.jay: Added error CS0145 test.
+
+2004-06-24  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (Operator.Define): Added test for errors CS0553, CS0554.
+
+2004-06-23  Ben Maurer  <bmaurer@ximian.com>
+       
+       * expression.cs (StackAlloc.Resolve): The argument may not
+       be a constant; deal with this case.
+       
+2004-06-23  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs (IndexerName_GetIndexerName): Renamed to
+       GetIndexerAttributeValue.
+       (ScanForIndexerName): Renamed to GetIndexerNameAttribute.
+
+       * class.cs (Indexer.Define): Added error tests for CS0415,
+       CS0609.
+
+2004-06-23  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs (Attribute.Resolve): Keep field code in sync with
+       property code.
+
+2004-06-23  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (UsageVector.MergeChild): If we're a loop and we
+       neither return nor throw, reset the barrier as well.  Fixes #60457.
+
+2004-06-22  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * class.cs : EventAttributes is now set to None by default.
+         This fixes bug #60459.
+
+2004-06-18  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #60219
+       * class.cs (ConstructorInitializer.GetOverloadedConstructor):
+       Don't throw exception but return null (it's sufficient now).
+
+2004-06-18  Marek Safar  <marek.safar@seznam.cz>
+
+       * typemanager.cs (GetArgumentTypes): Faster implementation.
+
+2004-06-18  Martin Baulig  <martin@ximian.com>
+
+       * attribute.cs (Attribute.Resolve): Check whether we're an
+       EmptyCast which a Constant child.  Fixes #60333.
+
+2004-06-17  Ben Maurer  <bmaurer@ximian.com>
+
+       * statement.cs (EmitCollectionForeach): Account for the fact that
+       not all valuetypes are in areas which we can take the address of.
+       For these variables, we store to a temporary variable. Also, make
+       sure that we dont emit a `callvirt' on a valuetype method.
+
+2004-06-15  Marek Safar  <marek.safar@seznam.cz>
+
+       * expression.cs (StackAlloc.DoReSolve): Added test for
+       negative parameter (CS0247).
+
+2004-06-15  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #59792
+       * class.cs: (Event.DelegateMethod.Emit): Added synchronization flag.
+
+2004-06-15  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #59781
+       * expression.cs: (Binary.DoNumericPromotions): Added conversion for
+       ulong.
+
+2004-06-14  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #58254 & cs1555.cs, cs1556.cs
+       * driver.cs (MainDriver): Added tests for errors CS1555, CS1556.
+
+2004-06-14  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Added error CS1669 test for indexers.
+
+2004-06-18  Martin Baulig  <martin@ximian.com>
+
+       * generics.cs (GenericMethod.ctor): Don't take an Attributes
+       argument.  Fixes #60441.
+
+2004-06-16  Ben Maurer  <bmaurer@ximian.com>
+       * ecore.cs (MethodGroupExpr.Name): Revert Martin's patch.
+       The name needs to have the actual name of the method in order
+       for other tests (such as the one in OverloadResolve for Invoke
+       on a delegate) to work. As well, it does not really help
+       error reporting because the method group had multiple methods.
+       * Makefile: Remove MCS_DEBUG, you can enable with the DEBUG_FLAGS.
+       Make profiling work.
+       
+2004-06-13  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay: Don't allow generic attributes.
+
+2004-06-13  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MemberBase.DoDefineBase): New protected method.
+       (MemberBase.DoDefine): Compute the `flags' in the new
+       DoDefineBase() which must be called first.
+       (Method.Define): Call DoDefineBase() first so we have the flags
+       when defining the generic method.
+
+       * cs-parser.jay (interface_method_declaration): Support generic methods.
+
+2004-06-13  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (TypeName): Removed.
+       (MemberName): Removed TypeName and MemberNow; now we just have
+       MemberName.
+
+       * cs-parser.jay: Don't distinguish between type arguments and type
+       parameters in the grammar and simplified the rules a bit.  The
+       reduce/reduce conflicts are now gone (except the one we inherited
+       from mcs).
+
+2004-06-11  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.IsParamsMethodApplicable): We need to
+       call this twice: for params and varargs methods.
+
+2004-06-11  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs:
+       (FieldBase.DoDefine, PropertyBase.DoDefine): Added error test CS0610.
+
+2004-06-11  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs (Attribute.GetValidTargets): Made public.
+
+       * class.cs: 
+       (AbstractPropertyEventMethod): New class for better code sharing.
+       (AbstractPropertyEventMethod.ApplyAttributeBuilder): Add error
+       CS1667 report.
+       (PropertyMethod, DelegateMethod): Derived from AbstractPropertyEventMethod
+
+2004-06-09  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay: Removed a reduce/reduce conflict.
+
+2004-06-03  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.GetMemberAccess): Renamed to
+       GetSimpleName() and return a SimpleName.
+
+       * ecore.cs (SimpleName.Arguments): New public field.
+       (SimpleName): Added overloaded ctor which takes an additional
+       TypeArguments argument.
+       (SimpleName.SimpleNameResolve): Added support for generic methods.
+       (MethodGroupExpr.ResolveGeneric): New public method.  The code was
+       formerly in MemberAccess.DoResolve(), but we also need it in
+       SimpleNameResolve().
+
+       * expression.cs (MemberAccess.DoResolve): Use the new
+       MethodGroupExpr.ResolveGeneric().       
+
+2004-05-30 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs: If possible, use lookuptypedirect here. We can only do
+       this if there is no `.' after the namespace. Avoids using
+       LookupType, which does lots of slow processing.
+       (FindNestedType) New method, does what it says :-).
+       * namespace.cs: use LookupTypeDirect.
+       * rootcontext.cs: use membercache, if possible.
+       * typemanager.cs (LookupTypeDirect): Cache negative hits too.
+
+2004-05-30 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs:
+       According to the spec, 
+
+       In a member access of the form E.I, if E is a single identifier,
+       and if the meaning of E as a simple-name (§7.5.2) is a constant,
+       field, property, localvariable, or parameter with the same type as
+       the meaning of E as a type-name (§3.8), then both possible
+       meanings of E are permitted.
+
+       We did not check that E as a simple-name had the same type as E as
+       a type name.
+
+       This trivial check gives us 5-7% on bootstrap time.
+
+2004-05-30 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs (Invocation.OverloadResolve): Avoid the
+       use of hashtables and boxing here by allocating on demand.
+
+2004-05-30  Martin Baulig  <martin@ximian.com>
+
+       * rootcontext.cs (RootContext.LookupType): Don't cache things if
+       we're doing a silent lookup.  Don't try to lookup nested types in
+       TypeManager.object_type (thanks to Ben Maurer).
+
+2004-05-30  Martin Baulig  <martin@ximian.com>
+
+       Committing a patch from Ben Maurer.
+
+       * rootcontext.cs (RootContext.LookupType): Cache negative results.
+
+2004-05-30 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * convert.cs: add a trivial cache for overload operator resolution.
+
+2004-05-31  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs
+       (AttributeTester.GetObsoleteAttribute): Returns instance of
+       ObsoleteAttribute when type is obsolete.
+
+       * class.cs
+       (TypeContainer.VerifyObsoleteAttribute): Override.
+       (Method.GetSignatureForError): New method for usage when MethodBuilder is null.
+       (MethodCode.VerifyObsoleteAttribute): Override.
+       (MemberBase.VerifyObsoleteAttribute): Override.
+
+       * decl.cs
+       (MemberCore.CheckUsageOfObsoleteAttribute): Tests presence of ObsoleteAttribute
+       and report proper error.
+
+       *delegate.cs
+       (Delegate.VerifyObsoleteAttribute): Override.
+
+       * ecore.cs
+       (Expression.CheckObsoleteAttribute): Tests presence of ObsoleteAttribute
+       and report proper error.
+       (FieldExpr.DoResolve): Added tests for ObsoleteAttribute.
+
+       * enum.cs
+       (Enum.GetObsoleteAttribute): Returns ObsoleteAttribute for both enum type
+       and enum member.
+
+       * expression.cs
+       (Probe.DoResolve, Cast.DoResolve, LocalVariableReference.DoResolve,
+       New.DoResolve, SizeOf.DoResolve, TypeOf.DoResolce, MemberAccess.DoResolve):
+       Added test for ObsoleteAttribute.
+
+       * statement.cs
+       (Catch): Derived from Statement.
+
+2004-05-30 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs: If possible, use lookuptypedirect here. We can only do
+       this if there is no `.' after the namespace. Avoids using
+       LookupType, which does lots of slow processing.
+       (FindNestedType) New method, does what it says :-).
+       * namespace.cs: use LookupTypeDirect.
+       * rootcontext.cs: use membercache, if possible.
+       * typemanager.cs (LookupTypeDirect): Cache negative hits too.
+
+2004-05-30 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs:
+       According to the spec, 
+
+       In a member access of the form E.I, if E is a single identifier,
+       and if the meaning of E as a simple-name (§7.5.2) is a constant,
+       field, property, localvariable, or parameter with the same type as
+       the meaning of E as a type-name (§3.8), then both possible
+       meanings of E are permitted.
+
+       We did not check that E as a simple-name had the same type as E as
+       a type name.
+
+       This trivial check gives us 5-7% on bootstrap time.
+
+2004-05-30  Marek Safar  <marek.safar@seznam.cz>
+
+       Fixed bug #59071 & cs0160.cs
+       * statement.cs (Try.Resolve): Check here whether order of catch
+       clauses matches their dependencies.
+
+2004-05-30  Marek Safar  <marek.safar@seznam.cz>
+
+       Fixed bug #58624
+       * ecore.cs (SimpleName.SimpleNameResolve): Added test for
+       unsafe type.
+
+2004-05-30 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs (Invocation.OverloadResolve): Avoid the
+       use of hashtables and boxing here by allocating on demand.
+
+2004-05-30  Martin Baulig  <martin@ximian.com>
+
+       * rootcontext.cs (RootContext.LookupType): Don't cache things if
+       we're doing a silent lookup.  Don't try to lookup nested types in
+       TypeManager.object_type (thanks to Ben Maurer).
+
+2004-05-30  Martin Baulig  <martin@ximian.com>
+
+       Committing a patch from Ben Maurer.
+
+       * rootcontext.cs (RootContext.LookupType): Cache negative results.      
+
+2004-05-29  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (IMethodData.ShouldIgnore): New method.
+
+       * typemanager.cs (TypeManager.MethodFlags): Don't take a
+       `Location' argument, we don't need it anywhere.  Use
+       `IMethodData.ShouldIgnore ()' instead of
+       `MethodData.GetMethodFlags ()'.
+       (TypeManager.AddMethod): Removed.
+       (TypeManager.AddMethod2): Renamed to AddMethod.
+
+2004-05-29  Martin Baulig  <martin@ximian.com>
+
+       Committing a patch from Benjamin Jemlich <pcgod@gmx.net>.
+
+       * convert.cs (Convert.ImplicitReferenceConversion): If we're
+       converting from a class type S to an interface type and we already
+       have an object on the stack, don't box it again.  Fixes #52578.
+
+2004-05-29  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (ConstructorInitializer.GetOverloadedConstructor):
+       Added support for `params' parameters.  Fixes #59267.
+
+2004-05-29  Martin Baulig  <martin@ximian.com>
+
+       * literal.cs (NullPointer): Provide a private .ctor which sets
+       `type' to TypeManager.object_type.  Fixes #59048.
+
+2004-05-29  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (MemberAccess.ResolveMemberAccess): If we're an
+       EventExpr, set `ee.InstanceExpression = left'.  Fixes #59188.
+
+       * ecore.cs (EventExpr.instance_expr): Make the field private.
+
+2004-05-26  Marek Safar  <marek.safar@seznam.cz>
+
+       Fixed bug #50080 & cs0214-2.cs
+       * expression.cs (Cast.DoResolve): Check unsafe context here.
+        
+       * statement.cs (Resolve.DoResolve): Likewise.
+
+2004-05-26  Martin Baulig  <martin@ximian.com>
+
+       * namespace.cs (NamespaceEntry.Lookup): Added `bool silent'.
+
+       * rootcontext.cs (RootContext.NamespaceLookup): Added `bool silent'.
+       (RootContext.LookupType): Pass down the `silent' flag.
+
+2004-05-25  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs
+       (MethodGroupExpr.IdenticalTypeName): New public property.
+       (Invocation.DoResolve): Don't report a CS0176 if the "instance"
+       expression actually refers to a type.
+
+2004-05-25  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.DoResolve): Applied Ben Maurer's patch
+       for #56176 and made it actually work.
+
+2004-05-25  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (Expression.CacheTemporaries): Make this virtual.
+       (FieldExpr, PropertyExpr): Override and implement
+       CacheTemporaries.  Fixes #52279.
+
+2004-05-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * location.cs: In the new compiler listing a file twice is a
+       warning, not an error.
+
+2004-05-24  Martin Baulig  <martin@ximian.com>
+
+       * enum.cs (Enum.DefineType): For the `BaseType' to be a
+       TypeLookupExpression; otherwise, report a CS1008.  Fixes #58571.
+
+2004-05-24  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.FindType): Try doing an alias lookup before
+       walking the `using' list.  Fixes #53921.
+
+2004-05-24  Martin Baulig  <martin@ximian.com>
+
+       * const.cs (Const.LookupConstantValue): Added support for
+       EmptyCast's; fixes #55251.
+
+2004-05-24  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Renamed to
+       DoSimpleNameResolve() and provide a SimpleNameResolve() wrapper
+       which does the CS0135 check.  The reason is that we first need to
+       check whether the variable actually exists.
+
+2004-05-24  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MemberBase.DoDefine): Use DeclSpace.FindType() rather
+       than RootContext.LookupType() to find the explicit interface
+       type.  Fixes #58584.
+
+2004-05-24  Raja R Harinath  <rharinath@novell.com>
+
+       * Makefile: Simplify.  Use executable.make.
+       * mcs.exe.sources: New file.  List of sources of mcs.exe.
+
+2004-05-24  Anders Carlsson  <andersca@gnome.org>
+
+       * decl.cs:
+       * enum.cs:
+       Use the invariant culture when doing String.Compare for CLS case
+       sensitivity.
+       
+2004-05-23  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.FindType): Only check the `using' list if we
+       don't have any dots.  Fixes #52622, added cs0246-8.cs.
+
+       * namespace.cs (NamespaceEntry.Lookup): Likewise.
+
+2004-05-23  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs (MemberBase.Define): Reuse MemberType member for 
+       resolved type. Other methods can use it too.
+
+2004-05-23  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Only report a CS0135 if
+       the variable also exists in the current block (otherwise, we need
+       to report a CS0103).  Fixes #58670.
+
+2004-05-23  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (Reachability.Reachable): Compute this
+       on-the-fly rather than storing it as a field.
+
+2004-05-23  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (Reachability.And): Manually compute the
+       resulting `barrier' from the reachability.      
+       
+2004-05-23  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #57835
+       * attribute.cs (AttributeTester.GetMethodObsoleteAttribute): Returns
+       instance of ObsoleteAttribute when symbol is obsolete.
+
+       * class.cs
+       (IMethodData): Extended interface for ObsoleteAttribute support.
+
+2004-05-22  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs: Fix bug #55970
+
+2004-05-22  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #52705
+       * attribute.cs
+       (GetObsoleteAttribute): New method. Creates the instance of
+       ObsoleteAttribute.
+       (AttributeTester.GetMemberObsoleteAttribute): Returns instance of
+       ObsoleteAttribute when member is obsolete.
+       (AttributeTester.Report_ObsoleteMessage): Common method for
+       Obsolete error/warning reporting.
+
+       * class.cs
+       (TypeContainer.base_classs_type): New member for storing parent type.
+
+       * decl.cs
+       (MemberCore.GetObsoleteAttribute): Returns instance of ObsoleteAttribute
+       for this MemberCore.
+
+2004-05-21  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs, const.cs: Fix bug #58590
+
+2004-05-21  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowBranching.MergeTopBlock): Don't check for
+       out parameters if the end of the method is unreachable.  Fixes
+       #58098. 
+
+2004-05-21  Marek Safar  <marek.safar@seznam.cz>
+
+       * codegen.cs, cs-parser.jay: Removed SetAttributes method.
+       Hari was right, why extra method.
+
+2004-05-21  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs, cs-parser.jay: Fix errors/cs0579-7.cs.
+
+2004-05-20  Martin Baulig  <martin@ximian.com>
+
+       * delegate.cs: Convert this file to Unix mode - like the original
+       version in mcs is.
+
+2004-05-20  Martin Baulig  <martin@ximian.com>
+
+       * attribute.cs: Convert this file to Unix mode - like the original
+       version in mcs is.
+
+2004-05-19  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #58688 (MCS does not report error when the same attribute
+       is assigned twice)
+
+       * attribute.cs (Attribute.Emit): Distinction between null and default.
+
+2004-05-19  Raja R Harinath  <rharinath@novell.com>
+
+       * cs-parser.jay (attribute): Create a GlobalAttribute for the case
+       of a top-level attribute without an attribute target.
+       * attribute.cs (Attribute.Error_AttributeConstructorMismatch): 
+       Make non-static.
+       (Attribute.Conditional_GetConditionName), 
+       (Attribute.Obsolete_GetObsoleteMessage): Update.
+       (Attribute.IndexerName_GetIndexerName): New.  Attribute-specific
+       part of ScanForIndexerName.
+       (Attribute.CanIgnoreInvalidAttribute): New function.
+       (Attribute.ScanForIndexerName): Move to ...
+       (Attributes.ScanForIndexerName): ... here.
+       (Attributes.Attrs): Rename from now-misnamed AttributeSections.
+       (Attributes.Search): New internal variant that can choose not to
+       complain if types aren't resolved.  The original signature now
+       complains.
+       (Attributes.GetClsCompliantAttribute): Use internal variant, with
+       complaints suppressed.
+       (GlobalAttribute.CheckAttributeType): Overwrite ds.NamespaceEntry
+       only if it not useful.
+       (CanIgnoreInvalidAttribute): Ignore assembly attribute errors at
+       top-level for attributes that are shared between the assembly
+       and a top-level class.
+       * parameter.cs (ImplicitParameter): Rename from ParameterAtribute.
+       * class.cs: Update to reflect changes.
+       (DefineIndexers): Fuse loops.
+       * codegen.cs (GetAssemblyName): Update to reflect changes.  Accept
+       a couple more variants of attribute names.
+
+2004-05-18  Marek Safar  <marek.safar@seznam.cz>
+
+       Fix bug #52585 (Implemented explicit attribute declaration)
+
+       * attribute.cs:
+       (Attributable.ValidAttributeTargets): New abstract method. It gets
+       list of valid attribute targets for explicit target declaration.
+       (Attribute.Target): It holds target itself.
+       (AttributeSection): Removed.
+       (Attribute.CheckTargets): New method. It checks whether attribute
+       target is valid for the current element.
+
+       * class.cs:
+       (EventProperty): New class. For events that are declared like
+       property (with add and remove accessors).
+       (EventField): New class. For events that are declared like field.
+       class.cs
+
+       * cs-parser.jay: Implemented explicit attribute target declaration.
+
+       * class.cs, decl.cs, delegate.cs, enum.cs, parameter.cs:        
+       Override ValidAttributeTargets.
+
+       * parameter.cs:
+       (ReturnParameter): Class for applying custom attributes on 
+       the return type.
+       (ParameterAtribute): New class. Class for applying custom
+       attributes on the parameter type.
+
+2004-05-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (MemberBase.DoDefine): Pass UNSAFE on interface
+       definitions. 
+
+       (Method): Allow UNSAFE here.
+
+       * modifiers.cs: Support unsafe reporting.
+
+2004-05-17  Marek Safar  <marek.safar@seznam.cz>
+
+       * decl.cs: Fix bug #58478.
+
+2004-05-17  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * statement.cs: When checking for unreachable code on an EmptyStatement,
+       set the location. Fixes bug #58488.
+
+2004-05-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Add -pkg handling.
+
+       From Gonzalo: UseShelLExecute=false
+
+2004-05-12  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs:
+       (Attribute.GetAttributeTargets): New method. Gets AttributeTargets
+       for attribute.
+       (Attribute.IsClsCompliaceRequired): Moved to base for better
+       accesibility.
+       (Attribute.UsageAttribute): New property for AttributeUsageAttribute
+       when attribute is AttributeUsageAttribute.
+       (Attribute.GetValidTargets): Simplified.
+       (Attribute.GetAttributeUsage): New method returns AttributeUsage
+       attribute for this type.
+       (Attribute.ApplyAttributes): Method renamed to Emit and make
+       non-static.
+       (GlobalAttributeSection): New class for special handling of global
+       attributes (assembly, module).
+       (AttributeSection.Emit): New method.
+
+       * class.cs: Implemented Attributable abstract methods.
+       (MethodCore.LabelParameters): Moved to Parameter class.
+       (Accessor): Is back simple class.
+       (PropertyMethod): Implemented Attributable abstract class.
+       (DelegateMethod): Implemented Attributable abstract class.
+       (Event): New constructor for disctintion between normal Event
+       and Event with accessors.
+
+       * cs-parser.jay: Used new Event ctor and GlobalAttributeSection.
+
+       * codegen.cs, const.cs, decl.cs, delegate.cs:
+       (CommonAssemblyModulClass): Implemented Attributable abstract class
+       and simplified.
+
+       * enum.cs: Implement IAttributeSupport interface.
+       (EnumMember): New class for emum members. Implemented Attributable
+       abstract class
+
+       * parameter.cs:
+       (ParameterBase): Is abstract.
+       (ReturnParameter): New class for easier [return:] attribute handling.
+
+       * typemanager.cs: Removed builder_to_attr.
+
+2004-05-11  Raja R Harinath  <rharinath@novell.com>
+
+       Fix bug #57151.
+       * attribute.cs (Attribute.GetPositionalValue): New function.
+       * class.cs (TypeContainer.VerifyMembers): New function.
+       (TypeContainer.Emit): Use it.
+       (ClassOrStruct): New base class for Class and Struct.
+       (ClassOrStruct.ApplyAttributeBuilder): New function.  Note if 
+       StructLayout(LayoutKind.Explicit) was ascribed to the struct or
+       class.
+       (ClassOrStruct.VerifyMembers): If the struct is explicitly laid out,
+       then each non-static field should have a FieldOffset attribute.
+       Otherwise, none of the fields should have a FieldOffset attribute.
+       * rootcontext.cs (RootContext.ResolveCore): Resolve StructLayout 
+       and FieldOffset attributes.
+       * typemanager.cs (TypeManager.struct_layout_attribute_type)
+       (TypeManager.field_offset_attribute_type): New core types.
+       (TypeManager.InitCoreTypes): Initialize them.
+
+2004-05-11  Michal Moskal  <malekith@pld-linux.org>
+
+       * class.cs (Event.RemoveDelegateMethod.DelegateMethodInfo):
+       Return correct type.
+       From bug #58270.
+
+2004-05-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Binary.DoNumericPromotions): 0 long constant can
+       be implicitly converted to ulong.
+       
+       * expression.cs: The logic for allowing operator &, | and ^ worked
+       was wrong, it worked before because we did not report an error in
+       an else branch.  Fixes 57895.
+
+       * class.cs: Applied patch from iain@mccoy.id.au Iain McCoy to
+       allow volatile fields to be reference types.
+
+2004-05-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Add support for /debug-
+
+2004-05-07  Raja R Harinath  <rharinath@novell.com>
+
+       * attribute.cs (Attribute.CheckAttributeType, Attribute.ResolveType): 
+       Add a 'complain' parameter to silence errors.
+       (Attribute.Resolve): Update to changes.  Put in sanity check to catch
+       silently overlooked type-resolutions.
+       (Attribute.ScanForIndexerName, Attribute.DefinePInvokeMethod): Update
+       to reflect changes.
+       (Attributes.Search): New function.
+       (Attributes.Contains, Attributes.GetClsCompliantAttribute): Use Search.
+       (Attributes.GetAttributeFullName): Remove hack.
+       * class.cs (MethodCore.LabelParameters, MethodData.ApplyAttributes): 
+       Update to reflect changes.
+       * codegen.cs (CommonAssemblyModulClass.GetClsCompliantAttribute):
+       Use Attributes.Search instead of nested loops.
+
+2004-05-07  Marek Safar  <marek.safar@seznam.cz>
+
+       * decl.cs:
+       (MemberCore.Flags): Extended for caching presence of CLSCompliantAttribute.
+       (MemberCore.VerifyClsCompliance): Implemented CS3019 error report.
+       (DeclSpace.GetClsCompliantAttributeValue): Returns simple bool.
+
+       * report.cs: (Report.Warning): Renamed to Warning_T because of
+       parameter collision.
+
+2004-05-05  Raja R Harinath  <rharinath@novell.com>
+
+       * expression.cs (MemberAccess.ResolveMemberAccess):
+       Exit with non-zero status after Report.Error.
+       * rootcontext.cs (RootContext.BootstrapCorlib_ResolveDelegate):
+       Likewise.
+       * typemanager.cs (TypeManager.CoreLookupType): Likewise.
+
+2004-05-04  Lluis Sanchez Gual  <lluis@ximian.com>
+
+       * support.cs: Don't hang when the file is empty.
+
+2004-05-04  Lluis Sanchez Gual  <lluis@ximian.com>
+
+       * support.cs: In SeekableStreamReader, compute the preamble size of the
+         underlying stream. Position changes should take into account that initial
+         count of bytes.
+
+2004-05-03  Todd Berman  <tberman@sevenl.net>
+
+       * driver.cs: remove unused GetSysVersion function.
+
+2004-05-03  Todd Berman  <tberman@sevenl.net>
+
+       * driver.cs: Remove the hack from saturday, as well as the hack
+       from jackson (LoadAssemblyFromGac), also adds the CWD to the
+       link_paths to get that bit proper.
+
+2004-05-01  Todd Berman  <tberman@sevenl.net>
+
+       * driver.cs: Try a LoadFrom before a Load, this checks the current
+       path. This is currently a bug in mono that is be fixed, however, this
+       provides a workaround for now. This will be removed when the bug
+       is fixed.
+
+2004-05-01  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * CryptoConvert.cs: Updated to latest version. Fix issue with 
+       incomplete key pairs (#57941).
+
+2004-05-01  Todd Berman  <tberman@sevenl.net>
+
+       * driver.cs: Remove '.' from path_chars, now System.* loads properly
+       from the GAC
+
+2004-04-30  Jackson Harper  <jackson@ximian.com>
+
+       * codegen.cs: Open keys readonly.
+       
+2004-04-30  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * typemanager.cs: don't report cyclic struct layout when a struct
+       contains 2 or more fields of the same type. Failed for Pango.AttrShape
+       which has 2 Pango.Rectangle fields.
+
+2004-04-29 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: Handle IntPtr comparisons with IL code
+       rather than a method call.
+
+2004-04-29  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (PropertyExpr.FindAccessor): New private method.  Walk
+       the list of PropertyInfo's in class hierarchy and find the
+       accessor.  Fixes #56013.
+
+2004-04-29  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.CheckStructCycles): Fixed.
+
+2004-04-29  Martin Baulig  <martin@ximian.com>
+
+       Applying a patch from Benjamin Jemlich <pcgod@gmx.net>.
+
+       * ecore.cs (FieldExpr.AddressOf): Make this work for valuetypes.
+
+2004-04-29  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (ConstructorInitializer.Resolve): Check whether the
+       parent .ctor is accessible.  Fixes #52146.
+
+2004-04-29  Martin Baulig  <martin@ximian.com>
+
+       Applying a patch from Benjamin Jemlich <pcgod@gmx.net>.
+
+       * statement.cs (Using.EmitLocalVariableDecls): Use
+       TypeManager.idisposable_type, not typeof (IDisposable).
+       (Foreach.EmitCollectionForeach): Added support for valuetypes.
+
+2004-04-29  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Event.Define): Don't emit the field and don't set
+       RTSpecialName and SpecialName for events on interfaces.  Fixes
+       #57703. 
+
+2004-04-29  Raja R Harinath  <rharinath@novell.com>
+
+       Refactor Attribute.ApplyAttributes.
+       * attribute.cs (Attributable): New base class for objects that can
+       have Attributes applied on them.
+       (Attribute): Make AttributeUsage fields public.
+       (Attribute.GetFieldValue, Attribute.GetMarshal): Make non-static.
+       (Attribute.IsInternalCall): New property.
+       (Attribute.UsageAttr): Convert to a public read-only property.
+       (Attribute.CheckAttributeType): Use a DeclSpace, not an EmitContext.
+       (Attribute.ResolveType, Attribute.Resolve)
+       (Attribute.ScanForIndexerName): Update to reflect changes.
+       (Attribute.CheckAttributeTarget): Re-format.
+       (Attribute.ApplyAttributes): Refactor, to various
+       Attributable.ApplyAttributeBuilder methods.
+       * decl.cs (MemberCore): Make Attributable.
+       * class.cs (Accessor): Make Attributable.
+       (MethodData.ApplyAttributes): Use proper attribute types, not
+       attribute names.
+       (TypeContainer.LabelParameters): Pass Parameter to ApplyAttributes.
+       (TypeContainer.ApplyAttributeBuilder)
+       (Method.ApplyAttributeBuilder, Constructor.ApplyAttributeBuilder)
+       (Field.ApplyAttributeBuilder, Accessor.ApplyAttributeBuilder)   
+       (PropertyBase.ApplyAttributeBuilder, Event.ApplyAttributeBuilder)
+       (Operator.ApplyAttributeBuilder): New factored-out methods.
+       * const.cs (Const.ApplyAttributeBuilder): Likewise.
+       * delegate.cs (Delegate.ApplyAttributeBuilder): Likewise.
+       * enum.cs (Enum.ApplyAttributeBuilder): Likewise.
+       * parameter.cs (ParameterBase): New Attributable base class
+       that can also represent Return types.
+       (Parameter): Update to the changes.
+
+2004-04-29  Jackson Harper  <jackson@ximian.com>
+
+       * driver.cs: Prefer the corlib system version when looking for
+       assemblies in the GAC. This is still a hack, but its a better hack
+       now.
+       
+2004-04-29  Marek Safar  <marek.safar@seznam.cz>
+
+       * decl.cs, enum.cs: Improved error 3005 reporting.
+  
+       * report.cs (SymbolRelatedToPreviousError): New method for error reporting.
+        (related_symbols): New private member for list of symbols
+       related to reported error/warning.
+        
+       * tree.cs: Do not use now obsolete Report.LocationOfPreviousError.
+
+2004-04-29  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (Expression.Constantify): If we're an enum and
+       TypeManager.TypeToCoreType() doesn't give us another type, use
+       t.UnderlyingSystemType.  Fixes #56178.  
+
+2004-04-29  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCache.SetupCacheForInterface): Look over all our
+       interfaces and for each interface, only add members directly
+       declared in that interface.  Fixes #53255.
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (ConditionalLogicalOperator): Use a temporary
+       variable for `left' to avoid that we evaluate it more than once;
+       bug #52588.
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (ComposedCast.DoResolveAsTypeStep): Don't allow
+       `void[]' (CS1547).
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (LocalInfo.Resolve): Check whether the type is not
+       void (CS1547).
+
+       * class.cs (MemberBase.CheckParameters, FieldBase.DoDefine): Check
+       whether the type is not void (CS1547).
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Unary.DoResolveLValue): Override this and report
+       CS0131 for anything but Operator.Indirection.
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       Committing a patch from Ben Maurer; see bug #50820.
+
+       * typemanager.cs (TypeManager.FilterWithClosure): Added CS1540
+       check for classes.
+
+       * ecore.cs (Expression.MemberLookupFailed): Added CS1540 check for
+       classes.        
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       Committing a patch from Ben Maurer; see bug #50820.
+
+       * typemanager.cs (TypeManager.FilterWithClosure): Added CS1540
+       check for classes.
+
+       * ecore.cs (Expression.MemberLookupFailed): Added CS1540 check for
+       classes.        
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Block.LookupLabel): Also lookup in implicit child blocks.
+       (Block.AddLabel): Call DoLookupLabel() to only search in the
+       current block.
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * cfold.cs (ConstantFold.BinaryFold): Added special support for
+       comparing StringConstants and NullLiterals in Equality and Inequality.
+
+2004-04-28  Jackson Harper  <jackson@ximian.com>
+
+       * driver.cs: Attempt to load referenced assemblies from the
+       GAC. This is the quick and dirty version of this method that
+       doesnt take into account versions and just takes the first
+       canidate found. Will be good enough for now as we will not have more
+       then one version installed into the GAC until I update this method.
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.CheckStructCycles): New public
+       static method to check for cycles in the struct layout.
+
+       * rootcontext.cs (RootContext.PopulateTypes): Call
+       TypeManager.CheckStructCycles() for each TypeContainer.
+       [Note: We only need to visit each type once.]
+
+2004-04-28  Martin Baulig  <martin@ximian.com>
+
+       * constant.cs (StringConstant.Emit): Emit Ldnull if we're null.
+
+       * const.cs (Const.LookupConstantValue): Return a `bool' signalling
+       success and added `out object value'.  Use a `bool resolved' field
+       to check whether we've already been called rather than
+       `ConstantValue != null' since this breaks for NullLiterals.
+
+2004-04-28  Raja R Harinath  <rharinath@novell.com>
+
+       * driver.cs (Driver.MainDriver) [IsModuleOnly]: Open code the
+       setting of this flag, since the 'set' method may be non-public.
+
+2004-04-28  Raja R Harinath  <rharinath@novell.com>
+
+       * flowanalysis.cs (FlowBranchingException.LookupLabel): Add a null
+       check on current_vector.Block.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (BaseAccess.CommonResolve): Don't allow `base' in
+       a field initializer.  Fixes #56459.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (PropertyExpr.DoResolve/DoResolveLValue): Check whether
+       we're not attempting to use an indexer.  Fixes #52154.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Return): Don't create a return label if we don't
+       need it; reverts my change from January 20th.  Thanks to Ben
+       Maurer for this.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       According to the spec, `goto' can only leave a nested scope, but
+       never enter it.
+
+       * statement.cs (Block.LookupLabel): Only lookup in the current
+       block, don't recurse into parent or child blocks.
+       (Block.AddLabel): Check in parent and child blocks, report
+       CS0140/CS0158 if we find a duplicate.
+       (Block): Removed this indexer for label lookups.
+       (Goto.Resolve): Call LookupLabel() on our current FlowBranching;
+       this already does the error reporting for us.
+
+       * flowanalysis.cs
+       (FlowBranching.UsageVector.Block): New public variable; may be null.
+       (FlowBranching.CreateSibling): Added `Block' argument.
+       (FlowBranching.LookupLabel): New public virtual method.  Lookup a
+       label for the target of a `goto' and check whether we're not
+       leaving a `finally'.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowBranching.UsageVector.MergeChild): If we're
+       a finite loop block, also do the ALWAYS->SOMETIMES for throws (not
+       just for returns).
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Block.AddLabel): Also check for implicit blocks
+       and added a CS0158 check.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowBranchingLoop): New class.
+       (FlowBranching.UsageVector.MergeJumpOrigins): Take a list of
+       UsageVector's instead of an ArrayList.
+       (FlowBranching.Label): Likewise.
+       (FlowBranching.UsageVector.MergeBreakOrigins): New method.
+       (FlowBranching.AddBreakVector): New method.
+
+2004-04-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs: Small regression fix: only convert the type if we
+       the type is different, fixes System.Drawing build.
+
+2004-04-27  Martin Baulig  <martin@ximian.com>
+
+       * attribute.cs (Attribute.Resolve): If we have a constant value
+       for a named field or property, implicity convert it to the correct
+       type.
+
+2004-04-27  Raja R Harinath  <rharinath@novell.com>
+
+       * statement.cs (Block.Block): Implicit blocks share
+       'child_variable_names' fields with parent blocks.
+       (Block.AddChildVariableNames): Remove.
+       (Block.AddVariable): Mark variable as "used by a child block" in
+       every surrounding block.
+       * ecore.cs (SimpleName.SimpleNameResolve): If the name has already
+       been used in a child block, complain about violation of "Invariant
+       meaning in blocks" rule.
+       * cs-parser.jay (declare_local_variables): Don't use
+       AddChildVariableNames.
+       (foreach_statement): Don't create an implicit block: 'foreach'
+       introduces a scope.
+
+2004-04-23  Miguel de Icaza  <miguel@ximian.com>
+
+       * convert.cs (ImplicitNumericConversion): 0 is also positive when
+       converting from 0L to ulong.  Fixes 57522.
+
+2004-04-22  Marek Safar  <marek.safar@seznam.cz>
+
+       * decl.cs (FindMemberToOverride): Fix wrong warning for case when
+        derived class hides via 'new' keyword field from base class (test-242.cs).
+        TODO: Handle this in the more general way.
+        
+       * class.cs (CheckBase): Ditto.
+
+2004-04-22  Marek Safar  <marek.safar@seznam.cz>
+
+       * decl.cs (caching_flags): New member for storing cached values
+       as bit flags.
+       (MemberCore.Flags): New enum where bit flags for caching_flags
+       are defined.
+       (MemberCore.cls_compliance): Moved to caching_flags.
+       (DeclSpace.Created): Moved to caching_flags.
+
+       * class.cs: Use caching_flags instead of DeclSpace.Created
+        
+2004-04-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (PropertyExpr.GetAccesor): Only perform the 1540 check
+       if we are only a derived class, not a nested class.
+
+       * typemanager.cs: Same as above, but do this at the MemberLookup
+       level (used by field and methods, properties are handled in
+       PropertyExpr).   Allow for the qualified access if we are a nested
+       method. 
+
+2004-04-21  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs: Refactoring.
+       (IMethodData): New inteface; Holds links to parent members
+       to avoid member duplication (reduced memory allocation).
+       (Method): Implemented IMethodData interface.
+       (PropertyBase): New inner classes for get/set methods.
+       (PropertyBase.PropertyMethod): Implemented IMethodData interface
+       (Event): New inner classes for add/remove methods.
+       (Event.DelegateMethod): Implemented IMethodData interface.
+
+       * cs-parser.jay: Pass DeclSpace to Event class for creation of valid
+       EmitContext (related to class.cs refactoring).
+
+2004-04-21  Raja R Harinath  <rharinath@novell.com>
+
+       * delegate.cs (Delegate.VerifyApplicability): If the number of
+       arguments are the same as the number of parameters, first try to
+       verify applicability ignoring  any 'params' modifier on the last
+       parameter.
+       Fixes #56442.
+
+2004-04-08  Martin Baulig  <martin@ximian.com>
+
+       Merged latest changes into gmcs.  Please keep this comment in
+       here, it makes it easier for me to see what changed in MCS since
+       the last time I merged.
+
+2004-04-16  Raja R Harinath  <rharinath@novell.com>
+
+       * class.cs (TypeContainer.AddIndexer): Use
+       'ExplicitInterfaceName' to determine if interface name was
+       explicitly specified.  'InterfaceType' is not initialized at this time.
+       (TypeContainer.DefineIndexers): Remove use of temporary list.  The
+       Indexers array is already in the required order.  Initialize
+       'IndexerName' only if there are normal indexers.
+       (TypeContainer.DoDefineMembers): Don't initialize IndexerName.
+       (TypeContainer.Emit): Emit DefaultMember attribute only if
+       IndexerName is initialized.
+       Fixes #56300.
+
+2004-04-15  Benjamin Jemlich  <pcgod@gmx.net>
+
+       * enum.cs (Enum.DefineType): Don't allow char as type for enum.
+       Fixes #57007
+
+2004-04-15  Raja R Harinath  <rharinath@novell.com>
+
+       * attribute.cs (Attribute.CheckAttributeType): Check for ambiguous
+       attributes.
+       Fix for #56456.
+
+       * attribute.cs (Attribute.Resolve): Check for duplicate named
+       attributes.
+       Fix for #56463.
+
+2004-04-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * iterators.cs (MarkYield): track whether we are in an exception,
+       and generate code accordingly.  Use a temporary value to store the
+       result for our state.
+
+       I had ignored a bit the interaction of try/catch with iterators
+       since their behavior was not entirely obvious, but now it is
+       possible to verify that our behavior is the same as MS .NET 2.0
+
+       Fixes 54814
+
+2004-04-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * iterators.cs: Avoid creating temporaries if there is no work to
+       do. 
+
+       * expression.cs (ArrayAccess.EmitLoadOpcode): If dealing with
+       Enumerations, use TypeManager.EnumToUnderlying and call
+       recursively. 
+
+       Based on the patch from Benjamin Jemlich (pcgod@gmx.net), fixes
+       bug #57013
+
+       (This.Emit): Use EmitContext.EmitThis to emit our
+       instance variable.
+
+       (This.EmitAssign): Ditto.
+
+       * ecore.cs (FieldExpr.Emit): Remove RemapToProxy special
+       codepaths, we will move all the functionality into
+       Mono.CSharp.This 
+
+       (FieldExpr.EmitAssign): Ditto.
+
+       This fixes several hidden bugs that I uncovered while doing a code
+       review of this today.
+
+       * codegen.cs (EmitThis): reworked so the semantics are more clear
+       and also support value types "this" instances.
+
+       * iterators.cs: Changed so that for iterators in value types, we
+       do not pass the value type as a parameter.  
+
+       Initialization of the enumerator helpers is now done in the caller
+       instead of passing the parameters to the constructors and having
+       the constructor set the fields.
+
+       The fields have now `assembly' visibility instead of private.
+
+2004-04-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Argument.Resolve): Check if fields passed as ref
+       or out are contained in a MarshalByRefObject.
+
+       * typemanager.cs, rootcontext.cs: Add System.Marshalbyrefobject as
+       another compiler type.
+
+2004-04-06 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * class.cs (Indexer.Define): use the new name checking method.
+       Also, return false on an error.
+       * cs-tokenizer.cs (IsValidIdentifier): Checks for a valid identifier.
+       (is_identifier_[start/part]_character): make static.
+
+2004-04-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Binary.ResolveOperator): Do no append strings
+       twice: since we can be invoked more than once (array evaluation)
+       on the same concatenation, take care of this here.  Based on a fix
+       from Ben (bug #56454)
+
+2004-04-08  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * codegen.cs: Fix another case where CS1548 must be reported (when 
+       delay-sign isn't specified and no private is available #56564). Fix
+       loading the ECMA "key" to delay-sign an assembly. Report a CS1548 
+       error when MCS is used on the MS runtime and we need to delay-sign 
+       (which seems unsupported by AssemblyBuilder - see #56621).
+
+2004-04-08  Marek Safar  <marek.safar@seznam.cz>
+
+       * typemanager.cs (TypeManager.TypeToCoreType): Handle IntPtr too.
+       (TypeManager.ComputeNamespaces): Faster implementation for
+       Microsoft runtime.
+
+       * compiler.csproj: Updated AssemblyName to mcs.
+
+2004-05-11  Jackson Harper  <jackson@ximian.com>
+
+       * Makefile: Preserve MONO_PATH
+       
+2004-05-11  Jackson Harper  <jackson@ximian.com>
+
+       * Makefile: Use mono and mcs to build gmcs
+       
+2004-05-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs: Add patch from Robert Shade
+       <rshade@dvsconsulting.com>, use FileAccess.Read on the keyfile, to
+       sync with mcs.
+
+2004-05-02  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * CryptoConvert.cs: Updated to latest version. Fix issue with 
+       incomplete key pairs (#57941).
+
+2004-04-08  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * codegen.cs: Fix another case where CS1548 must be reported (when 
+       delay-sign isn't specified and no private is available #56564). Fix
+       loading the ECMA "key" to delay-sign an assembly. Report a CS1548 
+       error when MCS is used on the MS runtime and we need to delay-sign 
+       (which seems unsupported by AssemblyBuilder - see #56621).
+
+2004-04-29  Jackson Harper  <jackson@ximian.com>
+
+       * Makefile: Set MONO_PATH to use the bootstrap corlib
+       * driver.cs: Check the GAC for referenced assemblies.
+               
+2004-04-29  Martin Baulig  <martin@ximian.com>
+
+       * Makefile (gmcs.exe): Set MONO_PATH to use `../class/lib/net_2_0'.
+
+2004-04-07  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Binary.ResolveOperator): Added special case for
+       Equality/Inequality between a type parameter and a null literal.
+
+2004-04-07  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs: Check null literal -> type parameter conversions.
+
+2004-04-07  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.CheckConstraints): Enforce the
+       `class' and `struct' constraints.
+
+2004-04-07  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (SpecialConstraint): New public enum.
+       (Constraints.Resolve): Added support for the `class' and `struct'
+       constraints.
+
+       * cs-parser.jay (type_parameter_constraint): Added support for the
+       `class' and `struct' constraints.
+
+2004-04-07  Martin Baulig  <martin@ximian.com>
+
+       * support.cs (GenericConstraints): Replaced `Types' by
+       `ClassConstraint' and `InterfaceConstraints'; added
+       `HasClassConstraint'.   
+
+2004-04-07  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs
+       (Constraints.InterfaceConstraints): New public property.
+       (Constraints.Types): Make this property public
+       (TypeParameter): Implement IMemberContainer.
+       (TypeParameter.Define): Take a `GenericTypeParameterBuilder'
+       instead of a TypeBuilder/MethodBuilder; pass the interface
+       constraints to TypeManager.AddTypeParameter().
+       (TypeParameter.DefineType): Just take an EmitContext and no
+       TypeBuilder/MethodBuilder.  Use the new public API.
+
+       * typemanager.cs (TypeManager.AddTypeParameter): Added
+       `TypeExpr[]' argument; add the interfaces to the
+       `builder_to_ifaces' hash.
+       (TypeManager.LookupMemberContainer): For
+       GenericTypeParameterBuilders, get the TypeParameter from the
+       `builder_to_type_param'.
+       (TypeManager.FindMembers): For GenericTypeParameterBuilders, get
+       the TypeParameter and call FindMembers on it.
+
+2004-04-07  Martin Baulig  <martin@ximian.com>
+
+       * class.cs
+       (MethodCore.GenericMethod): Moved this field here from Method.
+       (MethodCore.IsDuplicateImplementation): Take the number of type
+       parameters into account if we're a generic method.
+
+       * expression.cs (Invocation.InferTypeArguments): Don't return true
+       if `arguments' is null; we still need to check whether we actually
+       don't need to infer anything in this case.
+       (MemberAccess): Merged the functionality from GenericMemberAccess
+       into this class.
+
+       * generic.cs (GenericMemberAccess): Removed.
+
+2004-04-05  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCore): For generic classes, interfaces and
+       structs, `Name' now includes the number of type parameters
+       ("Stack!1.Node!1").
+       (DeclSpace.FindType): Removed the `num_type_args' argument; we now
+       encode the number of type arguments in the type name.
+
+       * expression.cs (Expression.MemberLookup): Removed the
+       `num_type_args' argument; we now encode the number of type
+       arguments in the type name.
+
+       * ecore.cs (SimpleName): Encode the number of type arguments in
+       the type name itself.
+
+       * generic.cs (ConstructedType): Likewise.
+
+       * tree.cs (Tree.RecordDecl): Take a `string' instead of a
+       `MemberName'; we now include the number of type parameters in the
+       type name.
+
+       * typemanager.cs (TypeManager.CheckGeneric): Removed.
+       (TypeManager.MemberLookup): Removed the
+       `num_type_args' argument; we now encode the number of type
+       arguments in the type name.     
+
+2004-04-03  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCore.ctor): Take a MemberName instead of a sting.
+       (MemberCore.MemberName): Moved here from MemberBase.
+       (DeclSpace.SetParameterInfo): Just take the constraints as an
+       ArrayList; we already have the type parameters in our
+       `MemberName'; also do the CS0080 reporting here.
+
+       * cs-parser.jay (struct_declaration): Use `member_name' instead of
+       `IDENTIFIER opt_type_parameter_list'; when constructing our
+       `MemberName', it'll already include our type parameters.
+       (class_declaration, interface_declaration): Likewise.
+       (delegate_declaration): Likewise.
+       (MakeName): Take a MemberName and return a MemberName.
+       The following two changes are required to avoid shift/reduce conflicts:
+       (member_name): Don't include a TypeName anymore; ie. this is now
+       just 'IDENTIFIER opt_type_parameter_list'.
+       (property_declaration, event_declaration): Use a
+       `namespace_or_type_name' instead of a `member_name'.            
+
+2004-04-03  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberName): Renamed to `TypeName' and created a new
+       `MemberName' class.
+       (TypeName): Formerly known as MemberName.
+
+       * namespace.cs (NamespaceEntry.UsingAlias): Take a `TypeName'
+       instead of a `MemberName'.
+
+       * cs-parser.jay (namespace_or_type_name): Create a TypeName.
+       (member_name): New rule; create a MemberName.
+
+2004-04-02  Martin Baulig  <martin@ximian.com>
+
+       * namespace.cs (NamespaceEntry.VerifyUsing): Added error checking
+       (CS0305 and CS0308).
+
+2004-04-02  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (GenericMemberAccess.ResolveAsTypeStep): Added
+       support for nested types.
+
+2004-04-02  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (IAlias): New public interface.
+       (TypeExpr, TypeExpression): Implement IAlias.
+       (TypeAliasExpression): New public class.
+
+       * namespace.cs (Namespace): Implement IAlias.
+       (Namespace.Lookup): Return an IAlias instead on an object.
+       (Namespace.DefineName): Take an IAlias instead of an object.
+       (NamespaceEntry.AliasEntry.Resolve): Return an IAlias instead of
+       an object.
+       (NamespaceEntry.UsingAlias): Take a Membername instead of an
+       Expression.
+       (NamespaceEntry.LookupAlias): Return an IAlias instead on an
+       object.
+       (NamespaceEntry.Lookup): Likewise.
+
+       * rootcontext.cs (RootContext.LookupType): Return a TypeExpr
+       instead of a Type.      
+
+       * decl.cs (DeclSpace): Implement IAlias.
+       (DeclSpace.LookupAlias): Return an IAlias instead of a string.
+
+       * generic.cs (ConstructedType): Improved error checking.
+
+2004-04-02  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs: Added type parameter conversions.
+
+       * ecore.cs
+       (UnboxCast.Emit): Emit an `unbox.any' for type params.
+       (ClassCast.Emit): If the source type is a type parameter, box it.
+       If the target type is a type parameter, emit an `unbox.any'
+       instead of a `classcast'.1      
+
+2004-04-01  Martin Baulig  <martin@ximian.com>
+
+       * cs-tokenizer.cs (parse_less_than): Allow Token.DOT.
+
+2004-04-01  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.CheckConstraints): Use
+       Convert.ImplicitStandardConversionExists(); user-defined implicit
+       conversions are not allowed according to the spec.
+
+2004-03-30  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (New): Added support for type parameters.
+
+       * typemanager.cs
+       (TypeManager.activator_type): New public static field.
+       (TypeManager.activator_create_instance): Likewise.
+
+2004-03-30  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.HasConstructorConstraint): New
+       public method.
+
+2004-03-30  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.CheckConstraints): Actually follow
+       the spec here: the argument type must be convertible to the
+       constraints.
+
+2004-03-30  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs
+       (TypeParameter.Define, TypeParameter.DefineMethod): Call
+       TypeManager.AddTypeParameter().
+       (ConstructedType.CheckConstraints): Re-enable this and actually
+       check whether we have a constructor constraint.
+
+       * typemanager.cs
+       (TypeManager.builder_to_type_param): New static field.
+       (TypeManager.AddTypeParameter): New static method.
+       (TypeManager.LookupTypeParameter): New public method.
+
+2004-03-30  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (TypeParameter.DefineType): Return a boolean and use
+       the new API to actually define the constructor constraint.
+
+       * typemanager.cs
+       (TypeManager.new_constraint_attr_type): New static field.
+       (TypeManager.InitCoreTypes): Initialize it.
+
+2004-03-30  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (Constraints): Completed error checking, use correct
+       error numbers.
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * delegate.cs (Delegate.VerifyMethod): Infer type arguments.
+
+       * expression.cs (Invocation.InferTypeArguments): Added overloaded
+       public version which takes a `ParameterData pd' instead of an
+       `ArrayList args'.
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.IsGenericMethod): Take a MethodBase,
+       not a MethodInfo.       
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Argument.ResolveMethodGroup): If we're a
+       ConstructedType, call GetMemberAccess() on it.  
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodBase.CheckGenericOverride): New abstract method.
+       (MethodCore.CheckGenericOverride): When overriding a generic
+       method, check whether the constraints match.
+
+       * support.cs (GenericConstraints): New public interface.
+       (ParameterData.GenericConstraints): New public method.
+
+       * parameter.cs (Parameter.Resolve): Check whether we're a generic
+       method parameter and compute our constraints if appropriate.
+       (Parameter.GenericConstraints): New public property.
+
+       * generic.cs (Constraints): Implement GenericConstraints.
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCache.FindMemberToOverride): Use
+       `paramTypes [j].Equals (cmpAttrs [j])' instead of `=='.
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (GenericMethod.Define): Resolve our type parameters.
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay: Report CS0080 instead of -200 ("Constraints are
+       not allowed on non-generic declarations").
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.InferTypeArguments): Added overloaded
+       public version of this method.
+
+       * class.cs (MethodCore.IsDuplicateImplementation): Use
+       Invocation.InferTypeArguments() to check this.
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs: Use TypeManager.IsDelegateType() instead of
+       comparing types correctly.
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs: Use TypeManager.IsSubclassOf() instead of comparing
+       types directly to make it work for generic instances.
+
+       * typemanager.cs (TypeManager.IsSubclassOf): New static method.
+
+2004-03-29  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.MayBecomeEqualGenericTypes): Added
+       support for arrays.     
+
+2004-03-24  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.FindType): Also use
+       TypeManager.CheckGeneric() for types from the using clauses.
+
+2004-03-23  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.OverloadResolve): Added `bool
+       may_fail' argument and use it instead of the Location.IsNull() hack.
+
+2004-03-23  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.InferType): Use correct type inference
+       rules here.     
+
+2004-03-23  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (MethodGroupExpr.Name): Use
+       TypeManager.CSharpSignature() instead of just the name.
+
+       * expression.cs (Invocation.OverloadResolve): Provide better error
+       reporting.
+       (Invocation.DoResolve): OverloadResolve() never returns null
+       without reporting an error, so removed the error -6 reporting here.
+
+2004-03-23  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.GetMethodFlags): Fixed the FIXME for
+       generic methods.
+
+       * cs-parser.jay (delegate_declaration): Support generic delegates.
+
+       * delegate.cs: Support generic delegates.
+
+2004-03-22  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.InferParamsTypeArguments): New static
+       method; does type inference for params arguments.
+
+2004-03-21  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.IsGenericMethod): New public static
+       method; checks whether a method is a generic method.    
+
+       * expression.cs (Invocation.InferTypeArguments): New static method;
+       infer type arguments for generic method invocation.
+
+       * ecore.cs (MethodGroupExpr.HasTypeArguments): New public
+       property; we set this to true if we're resolving a generic method
+       invocation and the user specified type arguments, ie. we're not
+       doing type inference.
+
+2004-03-20  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodData.DeclaringType): New public property.
+       (MethodData.Define): Set DeclaringType here.
+       (Operator.Define): Use OperatorMethod.MethodData.DeclaringType
+       instead of OperatorMethodBuilder.DeclaringType.
+
+2004-03-20  Martin Baulig  <martin@ximian.com>
+
+       * cs-tokenizer.cs (xtoken): Return a special
+       Token.DEFAULT_OPEN_PARENS for "`default' followed by open parens".
+
+       * cs-parser.jay (default_value_expression): Switch to the new
+       syntax (14.5.13).
+
+2004-03-19  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberName): New class.  We use this to "construct"
+       namespace_or_type_name's.
+
+       * generics.cs (TypeArguments.GetDeclarations): New public method;
+       returns the type arguments as a string[] and reports a CS0081 if
+       one of them is not an identifier.
+
+       * class.cs (MemberBase): The .ctor now takes the name as a
+       MemberName instead of a string.
+       (MemberBase.ExplicitInterfaceName): Changed type from string to
+       Expression.
+       (MemberBase.DoDefine): If we're an explicit implementation, the
+       InterfaceType may be a generic instance.
+
+       * cs-parser.jay (namespace_or_type_name): Return a MemberName.
+       (namespace_name): Call MemberName.GetName () to transform the
+       MemberName into a string and ensure we don't have any type
+       arguments.
+       (type_name): Call MemberName.GetTypeExpression() to transfrom the
+       MemberName into an expression.
+       (method_header): Use namespace_or_type_name instead of member_name.     
+
+2004-04-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs: Add new types to the boot resolution.
+
+       * ecore.cs (TypeExpr.CanInheritFrom): Inheriting from
+       MulticastDelegate is not allowed.
+
+       * typemanager.cs: Add new types to lookup: System.TypedReference
+       and ArgIterator.
+
+       * paramter.cs (Parameter.Resolve): if we are an out/ref parameter,
+       check for TypedReference or ArgIterator, they are not allowed. 
+
+       * ecore.cs (BoxedCast): Set the eclass to ExprClass.Value, this
+       makes us properly catch 1510 in some conditions (see bug 56016 for
+       details). 
+
+2004-04-06  Bernie Solomon  <bernard@ugsolutions.com>
+
+       * CryptoConvert.cs: update from corlib version
+       with endian fixes.
+
+2004-04-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Indexer.Define): Check indexername declaration
+
+2004-04-05  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs (IsClsCompliant): Fixed problem with handling
+       all three states (compliant, not-compliant, undetected).
+
+2004-03-30  Marek Safar  <marek.safar@seznam.cz>
+
+       * attribute.cs (Attribute): Location is now public.
+       (Resolve): Store resolved arguments (pos_values) in attribute class.
+       Attribute extractors (now GetClsCompliantAttributeValue) can reuse them.
+       (GetClsCompliantAttributeValue): New method that gets
+       CLSCompliantAttribute value.
+       (GetClsCompliantAttribute): Returns CLSCompliantAttribute for DeclSpace
+       if exists else null.
+       (AttributeTester): New class for CLS-Compliant verification routines.
+
+       * class.cs (Emit): Add CLS-Compliant verification.
+       (Method.GetSignatureForError): Implemented.
+       (Constructor.GetSignatureForError): Implemented
+       (Constructor.HasCompliantArgs): Returns if constructor has
+       CLS-Compliant arguments.
+       (Constructor.Emit): Override.
+       (Construcor.IsIdentifierClsCompliant): New method; For constructors
+       is needed to test only parameters.
+       (FieldBase.GetSignatureForError): Implemented.
+       (TypeContainer): New member for storing base interfaces.
+       (TypeContainer.FindMembers): Search in base interfaces too.
+
+       * codegen.cs (GetClsComplianceAttribute): New method that gets
+       assembly or module CLSCompliantAttribute value.
+       (ResolveClsCompliance): New method that resolve CLSCompliantAttribute
+       for assembly.
+       (ModuleClass.Emit): Add error 3012 test.
+
+       * const.cs (Emit): Override and call base for CLS-Compliant tests.
+
+       * decl.cs (ClsComplianceValue): New enum that holds CLS-Compliant
+       state for all decl types.
+       (MemberCore.Emit): Emit is now virtual and call VerifyClsCompliance
+       if CLS-Compliant tests are required.
+       (IsClsCompliaceRequired): New method. Analyze whether code
+       must be CLS-Compliant.
+       (IsExposedFromAssembly): New method. Returns true when MemberCore
+       is exposed from assembly.
+       (GetClsCompliantAttributeValue): New method. Resolve CLSCompliantAttribute
+       value or gets cached value.
+       (HasClsCompliantAttribute): New method. Returns true if MemberCore
+       is explicitly marked with CLSCompliantAttribute.
+       (IsIdentifierClsCompliant): New abstract method. This method is
+       used to testing error 3005.
+       (IsIdentifierAndParamClsCompliant): New method. Common helper method
+       for identifier and parameters CLS-Compliant testing.
+       (VerifyClsCompliance): New method. The main virtual method for
+       CLS-Compliant verifications.
+       (CheckAccessLevel): In one special case (System.Drawing) was TypeBuilder
+       null. I don't know why is null (too many public members !).
+       (GetClsCompliantAttributeValue). New method. Goes through class hierarchy
+       and get value of first CLSCompliantAttribute that found.
+
+       * delegate.cs (Emit): Override and call base for CLS-Compliant tests.
+       (VerifyClsCompliance): Override and add extra tests.
+
+       * driver.cs (CSCParseOption): New command line options (clscheck[+|-]).
+       clscheck- disable CLS-Compliant verification event if assembly is has
+       CLSCompliantAttribute(true).
+
+       * enum.cs (Emit): Override and call base for CLS-Compliant tests.
+       ApllyAttribute is now called in emit section as in the other cases.
+       Possible future Emit integration.
+       (IsIdentifierClsCompliant): New override.
+       (VerifyClsCompliance): New override.
+       (GetEnumeratorName): Returns full enum name.
+
+       * parameter.cs (GetSignatureForError): Implemented.
+
+       * report.cs (WarningData): New struct for Warning message information.
+       (LocationOfPreviousError): New method.
+       (Warning): New method. Reports warning based on the warning table.
+       (Error_T): New method. Reports error based on the error table.
+
+       * rootcontext.cs (EmitCode): Added new Emit(s) because CLS-Compliant
+       verifications are done here.
+
+       * tree.cs (RecordDecl): Used new LocationOfPreviousError method.
+
+       * typemanager.cs (cls_compliant_attribute_type): New member thath holds
+       CLSCompliantAttribute.
+       (all_imported_types): New member holds all imported types from other
+       assemblies.
+       (LoadAllImportedTypes): New method fills static table with exported types
+       from all referenced assemblies.
+       (Modules): New property returns all assembly modules.
+
+2004-03-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Add a rule to catch wrong event syntax instead of
+       throwing a parser error.
+
+       * ecore.cs (PropertyExpr.GetAccessor): Apply patch from Patrik Reali
+       which removes the hardcoded get_/set_ prefixes for properties, as
+       IL allows for the properties to be named something else.  
+
+       Bug #56013
+
+       * expression.cs: Do not override operand before we know if it is
+       non-null.  Fix 56207
+
+2004-03-29 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * typemanager.cs: support for pinned variables.
+
+2004-03-29 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs, typemanager.cs: Avoid using an arraylist
+       as a buffer if there is only one result set.
+
+2004-03-29 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: Make sure you cant call a static method
+       with an instance expression, bug #56174.
+
+2004-03-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (IsDuplicateImplementation): Improve error reporting to
+       flag 663 (method only differs in parameter modifier).
+
+       * cs-tokenizer.cs: Do not require whitespace when a ( or " will do
+       in preprocessor directives.
+
+       * location.cs (LookupFile): Allow for the empty path.
+
+       * attribute.cs (DefinePInvokeMethod): Fix 56148;  I would like a
+       better approach for some of that patch, but its failing with the
+       CharSet enumeration.  For now try/catch will do.
+
+       * typemanager.cs: Do not crash if a struct does not have fields.
+       Fixes 56150.
+
+2004-03-28 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: cs0213, cant fix a fixed expression.
+       fixes 50231.
+
+2004-03-28 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * cs-parser.jay: detect invalid embeded statements gracefully.
+       bug #51113.
+
+2004-03-28 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * ecore.cs, typemanager.cs: Correct impl of cs1540 check.
+       As a regex:
+       s/
+       the invocation type may not be a subclass of the tye of the item/
+       The type of the item must be a subclass of the invocation item.
+       /g
+
+       Fixes bug #50820.
+
+2004-03-25  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * attribute.cs: Added methods to get a string and a bool from an
+       attribute. Required to information from AssemblyKeyFileAttribute,
+       AttributeKeyNameAttribute (string) and AssemblyDelaySign (bool).
+       * codegen.cs: Modified AssemblyName creation to include support for
+       strongnames. Catch additional exceptions to report them as CS1548.
+       * compiler.csproj: Updated include CryptoConvert.cs.
+       * compiler.csproj.user: Removed file - user specific configuration.
+       * CryptoConvert.cs: New. A COPY of the class CryptoConvert from 
+       Mono.Security assembly. The original class is maintained and tested in
+       /mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoConvert.cs.
+       * drivers.cs: Added support for /keyfile, /keycontainer and /delaysign
+       like CSC 8.0 (C# v2) supports.
+       * Makefile: Added CryptoConvert.cs to mcs sources.
+       * rootcontext.cs: Added new options for strongnames.
+
+2004-03-24 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * driver.cs: For --expect-error, report error code `2'
+       if the program compiled with no errors, error code `1' if
+       it compiled with an error other than the one expected.
+
+2004-03-24  Sebastien Pouliot  <sebastien@ximian.com>
+
+       * compiler.csproj: Updated for Visual Studio .NET 2003.
+       * compiler.csproj.user: Updated for Visual Studio .NET 2003.
+       * compiler.sln: Updated for Visual Studio .NET 2003.
+
+2004-03-24  Ravi Pratap M  <ravi@ximian.com>
+
+       * expression.cs: Fix bug #47234. We basically need to apply the
+       rule that we prefer the conversion of null to a reference type
+       when faced with a conversion to 'object' (csc behaviour).
+
+2004-03-23 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * statement.cs: Shorter form for foreach, eliminates
+       a local variable. r=Martin.
+
+2004-03-23 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * constant.cs, ecore.cs, literal.cs: New prop IsZeroInteger that
+       checks if we can use brtrue/brfalse to test for 0.
+       * expression.cs: use the above in the test for using brtrue/brfalse.
+       cleanup code a bit.
+
+2004-03-23 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: Rewrite string concat stuff. Benefits:
+
+       - "a" + foo + "b" + "c" becomes "a" + foo + "bc"
+       - "a" + foo + "b" + bar + "c" + baz ... uses concat (string []).
+       rather than a concat chain.
+
+       * typemanager.cs: Add lookups for more concat overloads.
+
+2004-03-23 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: Emit shorter il code for array init.
+
+       newarr
+       dup
+       // set 1
+
+       // set 2
+
+       newarr
+       stloc.x
+
+       ldloc.x
+       // set 1
+
+       ldloc.x
+       // set 2
+
+2004-03-22 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * statement.cs: Before, two switch blocks would be merged if the
+       total size of the blocks (end_item - begin_item + 1) was less than
+       two times the combined sizes of the blocks.
+
+       Now, it will only merge if after the merge at least half of the
+       slots are filled.
+
+       fixes 55885.
+
+2004-03-20  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * class.cs : csc build fix for GetMethods(). See bug #52503.
+
+2004-03-20 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: Make sure fp comparisons work with NaN.
+       This fixes bug #54303. Mig approved this patch a long
+       time ago, but we were not able to test b/c the runtime
+       had a related bug.
+
+2004-03-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (TypExpr.GetHashCode): implement this overload. 
+
+2004-03-19  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MemberCore.IsDuplicateImplementation): Check whether
+       two overloads may unify for some type parameter substitutions and
+       report a CS0408 if appropriate.
+
+2004-03-19  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MemberCore.IsDuplicateImplementation): Report the
+       error here and not in our caller.
+
+2004-03-19  Martin Baulig  <martin@ximian.com>
+
+       * interface.cs: Completely killed this file.
+       (Interface): We're now a TypeContainer and live in class.cs.
+
+       * class.cs (TypeContainer.GetClassBases): Added `bool is_iface'
+       argument; we're now also called for interfaces.
+       (TypeContainer.DefineMembers): Allow this method being called
+       multiple times.
+       (TypeContainer.GetMethods): New public method; formerly known as
+       Interface.GetMethod().  This is used by PendingImplementation.
+       (TypeContainer.EmitDefaultMemberAttr): Moved here from Interface;
+       it's now private and non-static.
+       (Interface): Moved this here; it's now implemented similar to
+       Class and Struct.
+       (Method, Property, Event, Indexer): Added `bool is_interface'
+       argument to their .ctor's.
+       (MemberBase.IsInterface): New public field.
+
+       * cs-parser.jay: Create normal Method, Property, Event, Indexer
+       instances instead of InterfaceMethod, InterfaceProperty, etc.
+       (opt_interface_base): Removed; we now use `opt_class_base' instead.
+       (InterfaceAccessorInfo): Create `Get' and `Set' Accessor's.
+
+2004-03-19  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodCore.IsDuplicateImplementation): New private
+       method which does the CS0111 checking.
+       (Method.CheckBase, Constructor.CheckBase, PropertyBase.CheckBase):
+       Use IsDuplicateImplementation().
+
+2004-03-17 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs (FindMemberToOverride): New method to find the correct
+       method or property to override in the base class.
+       * class.cs
+           - Make Method/Property use the above method to find the
+             version in the base class.
+           - Remove the InheritableMemberSignatureCompare as it is now
+             dead code.
+
+       This patch makes large code bases much faster to compile, as it is
+       O(n) rather than O(n^2) to do this validation.
+
+       Also, it fixes bug 52458 which is that nested classes are not
+       taken into account when finding the base class member.
+
+       Reviewed/Approved by Martin.
+
+2004-03-17  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (MemberAccess.DoResolve): Take the parent's number
+       of type arguments into account; use the `real_num_type_args'
+       approach like in DoResolveAsTypeStep().
+
+       * generic.cs (GenericMemberAccess.DoResolve): Make this work for
+       nested types.
+
+2004-03-17  Marek Safar  <marek.safar@seznam.cz>
+
+       * interface.cs: In all interface classes removed redundant
+       member initialization.
+
+2004-03-16  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.GetClassBases): Fix the CS0528 check.
+
+2004-03-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * decl.cs (DefineTypeAndParents): New helper method to define a
+       type's containers before the type itself is defined;  This is a
+       bug exposed by the recent changes to Windows.Forms when an
+       implemented interface was defined inside a class that had not been
+       built yet.   
+
+       * modifiers.cs (MethodAttr): All methods in C# are HideBySig.
+
+       (Check): Loop correctly to report errors modifiers
+       (UNSAFE was not in the loop, since it was the same as TOP).
+
+       * interface.cs: Every interface member now takes a ModFlags,
+       instead of a "is_new" bool, which we set on the base MemberCore. 
+
+       Every place where we called "UnsafeOk" in the interface, now we
+       call the proper member (InterfaceMethod.UnsafeOK) instead to get
+       the unsafe settings from the member declaration instead of the
+       container interface. 
+
+       * cs-parser.jay (opt_new): Allow unsafe here per the spec. 
+
+       * pending.cs (TypeAndMethods): Add `get_indexer_name' and
+       `set_indexer_name' to the pending bits (one per type).
+
+       We fixed a bug today that was picking the wrong method to
+       override, since for properties the existing InterfaceMethod code
+       basically ignored the method name.  Now we make sure that the
+       method name is one of the valid indexer names.
+
+2004-03-14  Gustavo Giráldez  <gustavo.giraldez@gmx.net>
+       * support.cs (SeekableStreamReader): Keep track of stream byte
+       positions and don't mix them with character offsets to the buffer.
+
+       Patch from Gustavo Giráldez
+
+2004-03-15  Marek Safar  <marek.safar@seznam.cz>
+
+       * interface.cs (InterfaceSetGetBase): Removed double member
+       initialization, base class does it as well.
+
+2004-03-13  Martin Baulig  <martin@ximian.com>
+
+       * class.cs: Reverted Miguel's latest commit; it makes mcs crash
+       when compiling corlib.
+
+2004-03-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * convert.cs (ExplicitConversion): We were reporting an error on
+       certain conversions (object_type source to a value type, when the
+       expression was `null') before we had a chance to pass it through
+       the user defined conversions.
+
+       * driver.cs: Replace / and \ in resource specifications to dots.
+       Fixes 50752
+
+       * class.cs: Add check for duplicate operators.  Fixes 52477
+
+2004-03-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Switch.SimpleSwitchEmit): Deal with default labels
+       that are in the middle of the statements, not only at the end.
+       Fixes #54987
+
+       * class.cs (TypeContainer.AddField): No longer set the
+       `HaveStaticConstructor' flag, now we call it
+       `UserDefineStaticConstructor' to diferentiate the slightly
+       semantic difference.
+
+       The situation is that we were not adding BeforeFieldInit (from
+       Modifiers.TypeAttr) to classes that could have it.
+       BeforeFieldInit should be set to classes that have no static
+       constructor. 
+
+       See:
+
+       http://www.yoda.arachsys.com/csharp/beforefieldinit.html
+
+       And most importantly Zoltan's comment:
+
+       http://bugzilla.ximian.com/show_bug.cgi?id=44229
+
+       "I think beforefieldinit means 'it's ok to initialize the type sometime 
+        before its static fields are used', i.e. initialization does not need
+        to be triggered by the first access to the type. Setting this flag
+        helps the JIT to compile better code, since it can run the static
+        constructor at JIT time, and does not need to generate code to call it
+        (possibly lots of times) at runtime. Unfortunately, mcs does not set
+        this flag for lots of classes like String. 
+        
+        csc sets this flag if the type does not have an explicit static 
+        constructor. The reasoning seems to be that if there are only static
+        initalizers for a type, and no static constructor, then the programmer
+        does not care when this initialization happens, so beforefieldinit
+        can be used.
+        
+        This bug prevents the AOT compiler from being usable, since it 
+        generates so many calls to mono_runtime_class_init that the AOT code
+        is much slower than the JITted code. The JITted code is faster, 
+        because it does not generate these calls if the vtable is type is
+        already initialized, which is true in the majority of cases. But the
+        AOT compiler can't do this."
+
+2004-03-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (MethodData.Emit): Refactor the code so symbolic
+       information is generated for destructors;  For some reasons we
+       were taking a code path that did not generate symbolic information
+       before. 
+
+2004-03-11 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * class.cs: Create a Constructor.CheckBase method that
+       takes care of all validation type code. The method
+       contains some code that was moved from Define.
+
+       It also includes new code that checks for duplicate ctors.
+       This fixes bug #55148.
+
+2004-03-09  Joshua Tauberer <tauberer@for.net>
+
+       * expression.cs (ArrayCreation): Fix: More than 6 nulls in
+       a { ... }-style array creation invokes EmitStaticInitializers
+       which is not good for reference-type arrays.  String, decimal
+       and now null constants (NullCast) are not counted toward
+       static initializers.
+
+2004-03-05  Martin Baulig  <martin@ximian.com>
+
+       * location.cs (SourceFile.HasLineDirective): New public field;
+       specifies whether the file contains or is referenced by a "#line"
+       directive.
+       (Location.DefineSymbolDocuments): Ignore source files which
+       either contain or are referenced by a "#line" directive.        
+
+2004-02-29  Ben Maurer <bmaurer@users.sourceforge.net>
+
+       * class.cs (Method.CheckBase): Avoid using FindMembers, we have
+       direct access to our parent, so check the method inline there.
+
+2004-02-27 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs (Invocation.EmitCall): Miguel's last commit
+       caused a regression. If you had:
+
+           T t = null;
+           t.Foo ();
+
+       In Foo the implict this would be null.
+
+2004-02-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Invocation.EmitCall): If the method is not
+       virtual, do not emit a CallVirt to it, use Call.
+
+       * typemanager.cs (GetFullNameSignature): Improve the method to
+       cope with ".ctor" and replace it with the type name.
+
+       * class.cs (ConstructorInitializer.Resolve): Now the method takes
+       as an argument the ConstructorBuilder where it is being defined,
+       to catch the recursive constructor invocations.
+
+2004-03-16  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (MemberAccess.DoResolve): If `expr' resolved to a
+       ConstructedType, call ResolveType() on it to get the type rather
+       than just using `expr.Type'.
+
+2004-03-16  Martin Baulig  <martin@ximian.com>
+
+       * generics.cs (ConstructedType.GetMemberAccess): Take the
+       EmitContext instead on the TypeExpr and use
+       ec.TypeContainer.CurrentType/ec.ContainerType.
+
+2004-03-16  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (SimpleName.DoResolveAsTypeStep): Lookup type
+       parameters before aliases.
+
+2004-03-16  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.MayBecomeEqualGenericInstances):
+       New oublic function; checks whether two generic instances may become
+       equal under some instantiations (26.3.1).
+
+       * class.cs (TypeContainer.Define): Call
+       TypeManager.MayBecomeEqualGenericInstances() and report CS0695 on
+       error.
+
+2004-03-16  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.GetClassBases): Moved
+       Error_TypeParameterAsBase() here and also check whether the base
+       class is not an attribute.
+
+2004-03-16  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.GetClassBases): Fix the CS0528 check.
+
+2004-03-16  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Error_TypeParameterAsBase): Use correct error number
+       here (CS0689).  
+
+2004-03-16  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.ResolveTypeExpr): Added more error checking
+       for generics.
+
+       * generics.cs (ConstructedType.DoResolveAsTypeStep): Added better
+       error reporting.
+
+2004-03-15  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.GetFullName): New public method.
+       (TypeManager.MemberLookup): Added `int_num_type_arguments'
+       argument; only return members with the correct number of type
+       arguments.
+       (TypeManager.CheckGeneric): Allow -1 to bypass the check.
+       (TypeManager.FilterWithClosure): Call CheckGeneric() to check
+       whether the number of type arguments matches.
+
+       * generic.cs (GenericMemberAccess.ResolveAsTypeStep): Allow `expr'
+       not being a ConstructedType; we can now do "typeof (Foo.Bar<U>)".
+
+       * expression.cs (MemberAccess): Added public `NumTypeArguments'
+       field; it's set by the protected .ctor when we're actually a
+       GenericMemberAccess.
+       (MemberAccess.ResolveAsTypeStep): Compute the total number of type
+       arguments and pass it to MemberLookupFinal ().
+
+       * ecore.cs (Expression.MemberLookup): Added `int
+       num_type_arguments' argument; only return members with the correct
+       number of type arguments.
+       (Expression.MemberLookupFailed): Check whether the MemberLookup
+       failed because we did not have the correct number of type
+       arguments; report CS0305 in this case.
+
+       * decl.cs (DeclSpace.ResolveTypeExpr): Don't report an error if
+       `e.ResolveAsTypeTerminal()' already did so.
+
+2004-03-15  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (Expression.ResolveLValue): Allow e.type being null if
+       we're a ConstructedType; in this case, the caller must report an
+       error (for instance CS0131).
+
+       * generic.cs (TypeArguments): Added Location argument to the .ctor.
+       (TypeArguments.Resolve): Actually report errors here.
+
+2004-03-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * pending.cs (TypeAndMethods): Add `get_indexer_name' and
+       `set_indexer_name' to the pending bits (one per type).
+
+       We fixed a bug today that was picking the wrong method to
+       override, since for properties the existing InterfaceMethod code
+       basically ignored the method name.  Now we make sure that the
+       method name is one of the valid indexer names.
+
+2004-03-15  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.IndexerPropertyName): Added support
+       for generic instances.
+
+2004-03-13  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.DefineType): Call
+       TypeManager.AddUserType() immediately after creating the
+       TypeBuilder; pass all type parameters when creating the
+       CurrentType.
+
+       * decl.cs (DeclSpace.FindNestedType): New public method.
+       (DeclSpace.FindType): Added `int num_type_args' argument; only
+       return types with the correct number of type parameters.
+       (DeclSpace.CountTypeParams): New public property.
+
+       * ecore.cs (SimpleName.ctor): Added overloaded version which takes
+       the number of type parameters; defaults to zero.
+
+       * generic.cs (TypeArguments.Count): New public property.
+       (ConstructedType.DoResolveAsTypeStep): First call
+       ds.FindNestedType() to find out whether we're nested in the
+       current generic type; in this case, we inherit all type parameters
+       from the current class.
+
+       * rootcontext.cs (RootContext.NamespaceLookup): Added `int
+       num_type_args' argument.
+       (RootContext.LookupType): Added overloaded version which takes the
+       number of type arguments; only return types with the correct
+       number of type arguments.
+
+       * typemanager.cs (TypeManager.CheckGeneric): New public function;
+       checks whether `Type t' has `int num_type_args'.
+
+2004-03-13  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (GenericMethod.DefineType): New method; calls
+       DefineType() on all the type parameters.
+
+       * class.cs (MethodData.ctor): Added `GenericMethod generic' argument.
+       (MethodData.Define): If we're a generic method, call
+       GenericMethod.DefineType() to define the type parameters.       
+
+2004-03-10  Martin Baulig  <martin@ximian.com>
+
+       * pending.cs (Pending.InterfaceMethod): Use TypeManager.IsEqual()
+       instead of IsAssignableFrom.    
+
+2004-03-10  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (FieldExpr.ctor): Use TypeManager.TypeToCoreType().
+
+       * support.cs (ParameterData.HasArrayParameter): New property.
+       (ReflectionParameters.ctor): Take a MethodBase instead of a
+       ParameterInfo[].  If we have any type parameters, get the generic
+       method definition and ask it whether we have variable arguments.
+
+2004-02-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * iterators.cs (IteratorHandler.IsIEnumerator, IsIEnumerable): New
+       routines to check if a type is an enumerable/enumerator allow
+       classes that implement the IEnumerable or IEnumerator interfaces.
+
+       * class.cs (Property, Operator): Implement IIteratorContainer, and
+       implement SetYields.
+
+       (Property.Define): Do the block swapping for get_methods in the
+       context of iterators.   We need to check if Properties also
+       include indexers or not.
+
+       (Operator): Assign the Block before invoking the
+       OperatorMethod.Define, so we can trigger the Iterator code
+       replacement. 
+
+       * cs-parser.jay (SimpleIteratorContainer): new helper class.  Both
+       Property and Operator classes are not created when we parse the
+       declarator but until we have the block completed, so we use a
+       singleton SimpleIteratorContainer.Simple to flag whether the
+       SetYields has been invoked.
+
+       We propagate this setting then to the Property or the Operator to
+       allow the `yield' to function.
+
+2004-02-25  Marek Safar  <marek.safar@seznam.cz>
+
+       * codegen.cs: Implemented attribute support for modules.
+       New AssemblyClass, ModuleClass and CommonAssemblyModulClass for
+       Assembly/Module functionality.
+
+       * attribute.cs, class.cs, cs-parser.jay, delegate.cs, driver.cs, enum.cs
+       interface.cs, rootcontext.cs, statement.cs, typemanager.cs:
+       Updated dependencies on CodeGen.ModuleBuilder and CodeGen.AssemblyBuilder.
+
+2004-02-16  Marek Safar  <marek.safar@seznam.cz>
+
+       * interface.cs (FindMembers): The operation is performed on all base
+       interfaces and not only on the first. It is required for future CLS Compliance patch.
+
+2004-02-12 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * statement.cs, codegen.cs:
+       This patch deals with patterns such as:
+
+       public class List : IEnumerable {
+
+               public MyEnumerator GetEnumerator () {
+                       return new MyEnumerator(this);
+               }
+
+               IEnumerator IEnumerable.GetEnumerator () {
+                       ...
+               }
+               
+               public struct MyEnumerator : IEnumerator {
+                       ...
+               }
+       }
+
+       Before, there were a few things we did wrong:
+       1) we would emit callvirt on a struct, which is illegal
+       2) we emited ldarg when we needed to emit ldarga
+       3) we would mistakenly call the interface methods on an enumerator
+       type that derived from IEnumerator and was in another assembly. For example:
+
+       public class MyEnumerator : IEnumerator
+
+       Would have the interface methods called, even if there were public impls of the
+       method. In a struct, this lead to invalid IL code.
+
+2004-02-11  Marek Safar  <marek.safar@seznam.cz>
+
+       * const.cs: Const is now derived from FieldBase. Method EmitConstant name
+         renamed to Emit.
+
+       * delegate.cs (Define): Fixed crash when delegate type is undefined.
+
+2004-02-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Fix small regression: we were not testing V2
+       compiler features correctly.
+
+       * interface.cs: If the emit context is null, then create one
+
+2004-02-09  Marek Safar  <marek.safar@seznam.cz>
+
+       * decl.cs (GetSignatureForError): New virtual method to get full name
+         for error messages.
+
+       * attribute.cs (IAttributeSupport): New interface for attribute setting.
+         Now it is possible to rewrite ApplyAttributes method to be less if/else.
+
+       * interface.cs : All InterfaceXXX classes are now derived from MemberCore.
+         Duplicated members and code in these classes has been removed.
+         Better encapsulation in these classes.
+
+2004-02-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs (Assign.DoResolve): When dealing with compound
+       assignments, there is a new rule in ECMA C# 2.4 (might have been
+       there before, but it is documented here) that states that in:
+
+       a op= b;
+
+       If b is of type int, and the `op' is a shift-operator, then the
+       above is evaluated as:
+
+       a = (int) a op b 
+
+       * expression.cs (Binary.ResolveOperator): Instead of testing for
+       int/uint/long/ulong, try to implicitly convert to any of those
+       types and use that in pointer arithmetic.
+
+       * delegate.cs (Error_NoMatchingMethodForDelegate): Compute the
+       method to print information for from the type, not from the
+       null-method we were given.
+
+2004-02-01  Duncan Mak  <duncan@ximian.com>
+
+       * cs-tokenizer.cs (get_cmd_arg): Skip over whitespace before
+       parsing for cmd, fixes bug #53694.
+
+2004-02-04  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs, decl.cs: Fixed problem where IndexerName attribute was ignored
+       in the member name duplication tests. Property and operator name duplication
+       was missing too (error tests cs0102-{2,3,4,5}.cs, cs0111-{3,4}.cs).
+
+2004-02-03  Marek Safar  <marek.safar@seznam.cz>
+
+       * interface.cs (PopulateMethod): Fixed crash when interface method
+       returns not existing type (error test cs0246-3.cs).
+
+2004-02-02  Ravi Pratap M <ravi@ximian.com>
+
+       * cs-parser.jay (interface_accessors): Re-write actions to also
+       store attributes attached to get and set methods. Fix spelling
+       while at it.
+
+       (inteface_property_declaration): Modify accordingly.
+
+       (InterfaceAccessorInfo): New helper class to store information to pass
+       around between rules that use interface_accessors.
+
+       * interface.cs (Emit): Apply attributes on the get and set
+       accessors of properties and indexers too.
+
+       * attribute.cs (ApplyAttributes): Modify accordingly to use the
+       right MethodBuilder when applying attributes to the get and set accessors.
+
+2004-01-31  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: Applied patch from Marek Safar to fix bug 53386
+
+2004-01-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: Handle #line hidden from PDC bits.
+
+2004-01-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Remove YIELD token, instead use the new grammar
+       changes that treat `yield' specially when present before `break'
+       or `return' tokens.
+
+       * cs-tokenizer.cs: yield is no longer a keyword.
+
+2004-01-23  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay, class.cs (DefineDefaultConstructor): Fixed ModFlags
+       setting for default constructors.
+       For default constructors are almost every time set wrong Modifier. The
+       generated IL code has been alright. But inside mcs this values was
+       wrong and this was reason why several of my CLS Compliance tests
+       failed.
+
+2004-02-27  Martin Baulig  <martin@ximian.com>
+
+       * generics.cs (ConstructedType.ResolveType): Make the nested type
+       stuff actually work.
+
+2004-02-25  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.CurrentTypeParameters): New protected
+       property; returns the type parameters just from the current type,
+       ie. with the ones from outer classes.
+       (DeclSpace.LookupGeneric): First search in the current class, then
+       in outer classes.
+       (DeclSpace.initialize_type_params): When hiding a type parameter
+       from an outer class, put it into the `type_param_list' anyways.
+
+       * expression.cs (MemberAccess.expr): Made this field protected.
+
+       * class.cs (TypeContainer.Define): The `CurrentType' just contains
+       the type parameters from the current class.
+
+       * generic.cs (ConstructedType.ResolveType): Support nested generic
+       types by taking the type parameters which we inherit from outer
+       classes into account.
+       (GenericMemberAccess.ResolveAsTypeStep): Override this and added
+       support for nested generic types.
+
+2004-02-23  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.IsGeneric): Make this a property instead of a
+       field and check whether we're nested inside a generic type.
+       (DeclSpace.ResolveType): If we're resolving to a generic type
+       definition, create a ConstructedType and return its resolved type.
+       (DeclSpace.initialize_type_params): New private method;
+       initializes the `type_param_list' field from the type parameters
+       from this and all enclosing classes.
+       (DeclSpace.TypeParameters): Call initialize_type_params() unless
+       we're already initialized.
+
+2004-02-23  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Method.Define): Create the generic method before
+       calling DoDefine().
+       (Memberbase.DoDefine): Added DeclSpace argument (in addition to
+       the TypeContainer one); we use this for generic methods.
+
+       * decl.cs (CheckAccessLevel): If we're a GenericMethod, use our
+       parent's TypeBuilder.
+
+2004-02-18  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (FieldExpr.DoResolveLValue): Use TypeManager.IsEqual()
+       to check for equality.
+
+2004-02-05  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (FieldExpr.DoResolveLValue): If we have an
+       `ec.TypeContainer.CurrentType', use it instead of
+       `ec.ContainerType' to check whether we're in the type's ctor.
+
+2004-01-29  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.DoResolve): If we're a
+       `ConstructedType', then we're actually a generic method, so
+       rewrite the expr as a GenericMemberAccess.
+
+       * cs-parser.jay (member_name): Don't use `namespace_or_type_name'
+       here; manually parse it into a string.
+
+2004-01-28  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.IsEqual): New static method.
+       (TypeManager.FilterWithClosure): Call TypeManager.IsEqual() to
+       check for equality instead of using `=='.
+
+2004-01-26  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.CurrentType): New public field.
+
+       * expression.cs (This.ResolveBase): If we have an
+       `ec.TypeContainer.CurrentType', use it instead of
+       `ec.ContainerType'.
+
+       * class.cs (TypeContainer.DefineType): If we're a generic type,
+       create the `CurrentType' (unresolved).
+       (TypeContainer.GenericType): New private field.
+       (TypeContainer.DefineMembers): If we have a `CurrentType', resolve
+       it and store it in `GenericType' before creating the MemberCache.
+       (TypeContainer.GetMembers): If we have a `GenericType', call
+       TypeManager.FindMembers() on it.
+
+       * interface.cs (Interface.GenericType): New private field.
+       (Interface.DefineType): If we're a generic type, create the
+       `CurrentType' (unresolved).
+       (Interface.DefineMembers): If we have a `CurrentType', resolve it
+       and store it in `GenericType' before creating the MemberCache.
+       (Interface.GetMembers): If we have a `GenericType', call
+       TypeManager.FindMembers() on it.
+
+2004-01-22  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay (namespace_or_type_name): Return an Expression,
+       not a QualifiedIdentifier.  This is what `type_name_expression'
+       was previously doing.
+       (type_name_expression): Removed; the code is now in
+       `namespace_or_type_name'.
+       (qualified_identifier): Removed, use `namespace_or_type_name'
+       instead.
+       (QualifiedIdentifier): Removed this class.      
+
+2004-01-22  Martin Baulig  <martin@ximian.com>
+
+       * namespace.cs (NamespaceEntry.UsingAlias): Take an Expression,
+       not a string as alias name.
+
+2004-01-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (FieldInfo.AddressOf): Revert patch from previous
+       #52730 bug, and instead compute correctly the need to use a
+       temporary variable when requesting an address based on the
+       static/instace modified of the field and the constructor.
+2004-01-21  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (SimpleName.ResolveAsTypeStep): Lookup in the current
+       class and namespace before looking up aliases.  Fixes #52517.
+
+2004-01-21  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (UsageVector.Merge): Allow variables being
+       assinged in a 'try'; fixes exception4.cs.
+
+2004-01-21  Marek Safar  <marek.safar@seznam.cz>
+       * class.cs : Implemented parameter-less constructor for TypeContainer
+
+       * decl.cs: Attributes are now stored here. New property OptAttributes
+
+       * delegate.cs, enum.cs, interface.cs: Removed attribute member.
+
+       * rootcontext.cs, tree.cs: Now use parameter-less constructor of TypeContainer
+
+2004-01-21  Marek Safar  <marek.safar@seznam.cz>
+
+       * typemanager.cs (CSharpSignature): Now reports also inner class name.
+         (CSharpSignature): New method for indexer and property signature.
+
+2004-01-21  Marek Safar  <marek.safar@seznam.cz>
+
+       * pending.cs (IsVirtualFilter): Faster implementation.
+
+2004-01-21  Marek Safar  <marek.safar@seznam.cz>
+
+       * typemanager.cs: Avoid inclusion of same assembly more than once.
+
+2004-01-21  Marek Safar  <marek.safar@seznam.cz>
+
+       * cs-parser.jay: Fixed problem where the last assembly attribute
+         has been applied also to following declaration (class, struct, etc.)
+         
+2004-01-21  Marek Safar  <marek.safar@seznam.cz>
+
+       * class.cs: Added error CS0538, CS0539 reporting.
+       Fixed crash on Microsoft runtime when field type is void.
+
+       * cs-parser.jay: Added error CS0537 reporting.
+
+       * pending.cs: Added error CS0535 reporting.
+       Improved error report for errors CS0536, CS0534.
+
+2004-01-20  Miguel de Icaza  <miguel@ximian.com>
+
+       Merge a few bits from the Anonymous Method MCS tree.
+
+       * statement.cs (ToplevelBlock): New class for toplevel methods,
+       will hold anonymous methods, lifted variables.
+
+       * cs-parser.jay: Create toplevel blocks for delegates and for
+       regular blocks of code. 
+
+2004-01-20  Martin Baulig  <martin@ximian.com>
+
+       * codegen.cs (EmitContext): Removed `InTry', `InCatch',
+       `InFinally', `InLoop', `TryCatchLevel', `LoopBeginTryCatchLevel'
+       and `NeedExplicitReturn'; added `IsLastStatement'.
+       (EmitContext.EmitTopBlock): Emit the explicit "ret" if we either
+       have a `ReturnLabel' or we're not unreachable.
+
+       * flowanalysis.cs (FlowBranching.MergeChild): Actually merge the
+       child's reachability; don't just override ours with it.  Fixes
+       #58058 (lluis's example).
+       (FlowBranching): Added public InTryOrCatch(), InCatch(),
+       InFinally(), InLoop(), InSwitch() and
+       BreakCrossesTryCatchBoundary() methods.
+
+       * statement.cs (Return): Do all error checking in Resolve().
+       Unless we are the last statement in a top-level block, always
+       create a return label and jump to it.
+       (Break, Continue): Do all error checking in Resolve(); also make
+       sure we aren't leaving a `finally'.
+       (Block.DoEmit): Set `ec.IsLastStatement' when emitting the last
+       statement in a top-level block.
+       (Block.Flags): Added `IsDestructor'.
+       (Block.IsDestructor): New public property.
+
+2004-01-20  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Break.DoEmit): Set ec.NeedExplicitReturn; fixes #52427.
+
+2004-01-20  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Statement.ResolveUnreachable): New public method.
+       (If, While): Do the dead-code elimination in Resolve(), not in Emit().
+       (Block.Resolve): Resolve unreachable statements.
+
+2004-01-19 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: We need to fix the case where we do
+       not have a temp variable here.
+
+       * assign.cs: Only expression compound assignments need
+       temporary variables.
+
+2004-01-19 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * flowanalysis.cs: Reduce memory allocation in a few ways:
+         - A block with no variables should not allocate a bit
+           vector for itself.
+         - A method with no out parameters does not need any tracking
+           for assignment of the parameters, so we need not allocate
+           any data for it.
+         - The arrays:
+               public readonly Type[] VariableTypes;
+               public readonly string[] VariableNames;
+           Are redundant. The data is already stored in the variable
+           map, so we need not allocate another array for it.
+         - We need to add alot of checks for if (params | locals) == null
+           due to the first two changes.
+
+2004-01-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (FieldExpr.AddressOf): For ValueTypes that do not
+       implement IMemoryLocation, we store a copy on a local variable and
+       take the address of it.  Patch from Benjamin Jemlich
+
+       * cs-parser.jay: Applied patch from Ben Maurer to the "type" rule
+       to use a special "type_name_expression" rule which reduces the
+       number of "QualifiedIdentifier" classes created, and instead
+       directly creates MemberAccess expressions.
+
+2004-01-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * convert.cs: Applied patch from Benjamin Jemlich (pcgod@gmx.net)
+       that fixes #52853.  Null literal assignment to ValueType
+
+       * class.cs (MethodData.Emit): Instead of checking the name of the
+       method to determine if its a destructor, create a new derived
+       class from Method called Destructor, and test for that.  
+
+       * cs-parser.jay: Create a Destructor object instead of a Method.  
+
+       Based on a fix from Benjamin Jemlich (pcgod@gmx.net)
+
+       Fixes: 52933
+
+2004-01-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Binary.ResolveOperator): Perform an implicit
+       conversion from MethodGroups to their delegate types on the
+       Addition operation.
+
+       * delegate.cs: Introduce a new class DelegateCreation that is the
+       base class for `NewDelegate' and `ImplicitDelegateCreation',
+       factor some code in here.
+
+       * convert.cs (Convert.ImplicitConversionStandard): Add an implicit
+       conversion from MethodGroups to compatible delegate types. 
+
+       * ecore.cs (Expression.Resolve): Do not flag error 654
+       (Methodgroupd needs parenthesis) if running on the V2 compiler, as
+       we allow conversions from MethodGroups to delegate types now.
+
+       * assign.cs (Assign.DoResolve): Do not flag errors on methodgroup
+       assignments in v2 either.
+
+2004-01-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (FieldExpr.AddressOf): Fix generated IL for accessing
+       static read-only fields in ctors.
+
+       Applied patch from Benjamin Jemlich 
+
+       * expression.cs (UnaryMutator): Avoid leaking local variables. 
+
+2004-01-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs (IsCastToken): Allow the various native types
+       here to return true, as they can be used like this:
+
+               (XXX) int.MEMBER ()
+
+       Fixed 49836 and all the other dups
+
+2004-01-09  Zoltan Varga  <vargaz@freemail.hu>
+
+       * driver.cs: Implement /win32res and /win32icon.
+
+2004-01-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Add a rule to improve error handling for the
+       common mistake of placing modifiers after the type.
+
+2004-01-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay (interface_event_declaration): Catch
+       initialization of events on interfaces, and report cs0068
+
+       * cs-parser.jay (interface_event_declaration): Catch
+       initialization of events. 
+
+       * ecore.cs: Better report missing constructors.
+
+       * expression.cs (Binary.ResolveOperator): My previous bug fix had
+       the error reporting done in the wrong place.  Fix.
+
+       * expression.cs (Binary.ResolveOperator): Catch the 
+       operator + (E x, E y) error earlier, and later allow for implicit
+       conversions in operator +/- (E e, U x) from U to the underlying
+       type of E.
+
+       * class.cs (TypeContainer.DefineDefaultConstructor): Fix bug
+       52596, if the container class is abstract, the default constructor
+       is protected otherwise its public (before, we were always public).
+
+       * statement.cs (Fixed.Resolve): Catch a couple more errors in the
+       fixed statement.
+
+       (Using.EmitLocalVariableDecls): Applied patch from Benjamin
+       Jemlich that fixes bug #52597, MCS was generating invalid code for
+       idisposable structs.   Thanks to Ben for following up with this
+       bug as well.
+
+2004-01-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Allow assemblies without code to be generated, fixes
+       52230.
+
+2004-01-07  Nick Drochak <ndrochak@gol.com>
+
+       * attribute.cs: Remove unneeded catch variables. Eliminates a warning.
+
+2004-01-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Add rules to improve error reporting if fields or
+       methods are declared at the namespace level (error 116)
+
+       * Add rules to catch event add/remove
+
+2004-01-04  David Sheldon <dave-mono@earth.li>
+
+  * expression.cs: Added matching ")" to error message for 
+  CS0077
+
+2004-01-03 Todd Berman <tberman@gentoo.org>
+
+       * ecore.cs, attribute.cs:
+       Applying fix from #52429.
+
+2004-01-03 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * ecore.cs, expression.cs, statement.cs:
+       Total rewrite of how we handle branching. We
+       now handle complex boolean expressions with fewer
+       jumps. As well if (x == 0) no longer emits a ceq.
+
+       if (x is Foo) is much faster now, because we generate
+       better code.
+
+       Overall, we get a pretty big improvement on our benchmark
+       tests. The code we generate is smaller and more readable.
+
+       I did a full two-stage bootstrap. The patch was reviewed
+       by Martin and Miguel.
+
+2004-01-03 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * cs-parser.jay: Make primary_expression not take a QI.
+       we dont need this because the member_access rule covers
+       us here. So we replace the rule with just IDENTIFIER.
+
+       This has two good effects. First, we remove a s/r conflict.
+       Second, we allocate many fewer QualifiedIdentifier objects.
+
+2004-01-03 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * attribute.cs: Handle MarshalAs attributes as pseudo, and
+       set the correct information via SRE. This prevents
+       hanging on the MS runtime. Fixes #29374.
+
+2004-01-03 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * convert.cs: correctly handle conversions to value types
+       from Enum and ValueType as unboxing conversions.
+
+       Fixes bug #52569. Patch by Benjamin Jemlich.
+
+2004-01-02  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (BetterConversion): Prefer int -> uint
+       over int -> ulong (csc's behaviour). This fixed bug #52046.
+
+2004-01-02 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs (MemberCache.FindMembers): now returns a
+       MemberInfo [].
+
+       * typemanager.cs: In general, go with with ^^.
+       (CopyNewMethods): take an IList.
+       (RealMemberLookup): Only allocate an arraylist
+       if we copy from two sets of methods.
+
+       This change basically does two things:
+       1) Fewer array lists allocated due to CopyNewMethods.
+       2) the explicit cast in MemberList costed ALOT.
+
+2004-01-02  Zoltan Varga  <vargaz@freemail.hu>
+
+       * cs-tokenizer.cs (consume_identifier) driver.cs: Cache identifiers in
+       a hashtable to avoid needless string allocations when an identifier is
+       used more than once (the common case).
+
+2004-01-01 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * pending.cs: MS's TypeBuilder.GetInterfaces ()
+       is broken, it will not return anything. So, we
+       have to use the information we have in mcs to
+       do the task.
+
+       * typemanager.cs: Add a cache for GetInterfaces,
+       since this will now be used more often (due to ^^)
+
+       (GetExplicitInterfaces) New method that gets the
+       declared, not effective, interfaces on a type
+       builder (eg, if you have interface IFoo, interface
+       IBar, Foo : IFoo, Bar : Foo, IBar, GetExplInt (Bar) ==
+       { IBar }.
+
+       This patch makes MCS able to bootstrap itself on
+       Windows again.
+
+2004-01-01 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: Remove the Nop's that Miguel put
+       in by mistake.
+
+2003-12-31 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * report.cs, codegen.cs: Give the real stack trace to
+       the error when an exception is thrown.
+
+2003-12-31 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs: only allocate hashtables for ifaces if 
+       it is an iface!
+
+2003-12-31 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: fix the error from cs0121-2.cs
+       (a parent interface has two child interfaces that
+       have a function with the same name and 0 params
+       and the function is called through the parent).
+
+2003-12-30 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * class.cs, rootcontext.cs, typmanager.cs: do not
+       leak pointers.
+
+2003-12-28 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * codegen.cs: remove stack for the ec flow branching.
+       It is already a linked list, so no need.
+
+2003-12-27 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * Makefile: Allow custom profiler here.
+
+2003-12-26 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * typemanager.cs (LookupType):
+         - Use a static char [], because split takes
+           a param array for args, so it was allocating
+           every time.
+         - Do not store true in a hashtable, it boxes.
+
+2003-12-26 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * flowanalysis.cs: bytify common enums.
+
+2003-12-25 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * modifiers.cs: Add a new set of flags for the
+       flags allowed on explicit interface impls.
+       * cs-parser.jay: catch the use of modifiers in
+       interfaces correctly.
+       * class.cs: catch private void IFoo.Blah ().
+
+       All related to bug #50572.
+
+2003-12-25 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs: Rewrite the consistant accessability checking.
+       Accessability is not linear, it must be implemented in
+       a tableish way. Fixes #49704.
+
+2003-12-25 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * expression.cs: Handle negation in a checked context.
+       We must use subtraction from zero. Fixes #38674.
+
+2003-12-23 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * class.cs: Ignore static void main in DLLs.
+       * rootcontext.cs: Handle the target type here,
+       since we are have to access it from class.cs
+       * driver.cs: account for the above.
+
+2003-12-23 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * report.cs: Give line numbers and files if available.
+
+2003-12-20  Zoltan Varga  <vargaz@freemail.hu>
+
+       * driver.cs: Implement /addmodule.
+
+       * typemanager.cs:  Change 'modules' field so it now contains Modules not
+       ModuleBuilders.
+
+2003-12-20  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.DefineMembers): Don't do the CS0649 check here.
+       (FieldBase.IsAssigned): Removed this field.
+       (FieldBase.SetAssigned): New public method.
+       (TypeContainer.Emit): Make the CS0169/CS0649 checks actually work.
+
+2003-12-20  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (LocalVariableReference.DoResolve): Don't set
+       `vi.Used' if we're called from DoResolveLValue().
+
+       * statement.cs (Block.DoResolve): `ec.DoEndFlowBranching()' now
+       returns the usage vector it just merged into the current one -
+       pass this one to UsageWarning().
+       (Block.UsageWarning): Take the `FlowBranching.UsageVector' instead
+       of the `EmitContext', don't call this recursively on our children.
+
+2003-12-19  Zoltan Varga  <vargaz@freemail.hu>
+
+       * driver.cs: Implement /target:module.
+
+2003-12-18  Zoltan Varga  <vargaz@freemail.hu>
+
+       * support.cs (CharArrayHashtable): New helper class.
+
+       * cs-tokenizer.cs: Store keywords in a hashtable indexed by 
+       char arrays, not strings, so we can avoid creating a string in
+       consume_identifier if the identifier is a keyword.
+
+2003-12-16  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (LocalInfo.Assigned): Removed this property.
+       (LocalInfo.Flags): Removed `Assigned'.
+       (LocalInfo.IsAssigned): New public method; takes the EmitContext
+       and uses flow analysis.
+       (Block.UsageWarning): Made this method private.
+       (Block.Resolve): Call UsageWarning() if appropriate.
+
+       * expression.cs (LocalVariableReference.DoResolve): Always set
+       LocalInfo.Used here.
+
+2003-12-13  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Statement.DoEmit, Statement.Emit): Don't return
+       any value here; we're now using flow analysis to figure out
+       whether a statement/block returns a value.
+
+2003-12-13  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (UsageVector.MergeFinallyOrigins): Made this
+       working again.
+       (FlowBranching.MergeFinally): Don't call
+       `branching.CheckOutParameters()' here, this is called in
+       MergeTopBlock().
+       (FlowBranchingException.AddSibling): Call MergeFinallyOrigins()
+       when adding the `finally' vector.       
+
+2003-12-13  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs
+       (UsageVector.MergeJumpOrigins, FlowBranching.Label): Make this
+       actually work and also fix #48962.
+
+2003-12-12 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * decl.cs: Do not check System.Object for nested types,
+       since we know it does not have any. Big bang for buck:
+
+       BEFORE:
+          Run 1:   8.35 seconds
+          Run 2:   8.32 seconds
+          corlib:  17.99 seconds
+       AFTER:
+          Run 1:   8.17 seconds
+          Run 2:   8.17 seconds
+          corlib:  17.39 seconds
+
+2003-12-11 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * class.cs (FindMembers): Allocate arraylists on demand. Most of the
+       time we are returning 0 members, so we save alot here.
+
+2003-12-11  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (UsageVector.MergeResult): Renamed this back to
+       `MergeChild()', also just take the `FlowBranching' as argument;
+       call Merge() on it and return the result.
+       (FlowBranching.Merge): We don't need to do anything if we just
+       have one sibling.
+
+2003-12-11  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs: Use a list of `UsageVector's instead of storing
+       them in an `ArrayList' to reduce memory usage.  Thanks to Ben
+       Maurer for this idea.
+
+2003-12-11  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (MergeResult): This class is now gone; we now
+       use the `UsageVector' for this.  The reason for this is that if a
+       branching just has one sibling, we don't need to "merge" them at
+       all - that's the next step to do.
+       (FlowBranching.Merge): We now return a `UsageVector' instead of a
+       `MergeResult'.
+
+2003-12-11  Martin Baulig  <martin@ximian.com>
+
+       Reworked flow analyis and made it more precise and bug-free.  The
+       most important change is that we're now using a special `Reachability'
+       class instead of having "magic" meanings of `FlowReturns'.  I'll
+       do some more cleanups and optimizations and also add some more
+       documentation this week.
+
+       * flowanalysis.cs (Reachability): Added `Throws' and `Barrier';
+       largely reworked this class.
+       (FlowReturns): Removed `Unreachable' and `Exception'; we now use
+       the new `Reachability' class instead of having "magic" values here.
+       (FlowBranching): We're now using an instance of `Reachability'
+       instead of having separate `Returns', `Breaks' etc. fields.
+
+       * codegen.cs (EmitContext.EmitTopBlock): Set `has_ret' solely
+       based on flow analysis; ignore the return value of block.Emit ().
+
+2003-12-10  Zoltan Varga  <vargaz@freemail.hu>
+
+       * driver.cs typemanager.cs: Find the mono extensions to corlib even
+       if they are private.
+
+2003-12-09  Martin Baulig  <martin@ximian.com>
+
+       * flowanalyis.cs (FlowBranching.Return, Goto, Throw): Removed;
+       call them directly on the UsageVector.
+
+2003-12-09  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowBranching.MergeChild, MergeTopBlock):
+       Changed return type from `FlowReturns' to `Reachability'.
+
+2003-12-09  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowBranching.Reachability): New sealed class.
+       (FlowBranching.MergeResult): Replaced the `Returns', `Breaks' and
+       `Reachable' fields with a single `Reachability' one.
+
+2003-12-08 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * class.cs (FindMembers): Remove foreach's.
+
+       Bootstrap times:
+
+       BEFORE
+               Run 1:   8.74 seconds
+               Run 2:   8.71 seconds
+
+       AFTER
+               Run 1:   8.64 seconds
+               Run 2:   8.58 seconds
+
+
+2003-12-08 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * cs-parser.jay:
+       * gen-treedump.cs:
+       * statement.cs:
+       This patch does a few things:
+               1. EmptyStatement is now a singleton, so it is never reallocated.
+               2. All blah is EmptyStatement constructs have been changed to
+                  blah == EmptyStatement.Value, which is much faster and valid
+                  now that EmptyStatement is a singleton.
+               3. When resolving a block, rather than allocating a new array for
+                  the non-empty statements, empty statements are replaced with
+                  EmptyStatement.Value
+               4. Some recursive functions have been made non-recursive.
+       Mainly the performance impact is from (3), however (1) and (2) are needed for
+       this to work. (4) does not make a big difference in normal situations, however
+       it makes the profile look saner.
+
+       Bootstrap times:
+
+       BEFORE
+       9.25user 0.23system 0:10.28elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k
+       9.34user 0.13system 0:10.23elapsed 92%CPU (0avgtext+0avgdata 0maxresident)k
+       Total memory allocated: 56397 KB
+
+       AFTER
+       9.13user 0.09system 0:09.64elapsed 95%CPU (0avgtext+0avgdata 0maxresident)k
+       8.96user 0.24system 0:10.13elapsed 90%CPU (0avgtext+0avgdata 0maxresident)k
+       Total memory allocated: 55666 KB
+
+2003-12-08 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * support.cs: Rewrite DoubleHash to use its own impl. Is faster
+       than the hashtable in a hashtable version
+
+       * decl.cs: Right now, whenever we try to lookup a type inside a namespace,
+       we always end up concating a string. This results in a huge perf
+       loss, because many strings have to be tracked by the GC. In this
+       patch, we first use a hashtable that works with two keys, so that
+       the strings do not need to be concat'ed.
+
+       Bootstrap times:
+       BEFORE
+               Run 1:   8.74 seconds
+               Run 2:   8.71 seconds
+
+       AFTER
+               Run 1:   8.65 seconds
+               Run 2:   8.56 seconds
+
+2003-12-08 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * Makefile: Add a new target `do-time' that does a quick and simple
+       profile, leaving easy to parse output.
+
+2003-12-08  Zoltan Varga  <vargaz@freemail.hu>
+
+       * codegen.cs (Init): Create the dynamic assembly with 
+       AssemblyBuilderAccess.Save, to enable some optimizations in the runtime.
+
+2003-12-02 Ben Maurer  <bmaurer@users.sourceforge.net>
+
+       * support.cs: Make the PtrHashtable use only one
+       instance of its comparer.
+
+2003-11-30  Zoltan Varga  <vargaz@freemail.hu>
+
+       * typemanager.cs: Fix lookup of GetNamespaces.
+
+2003-11-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Removed redundant line.
+
+       * statement.cs (Block.Resolve, Block.Emit): Avoid foreach on
+       ArrayLists, use for loops with bounds.  
+
+       * flowanalysis.cs (FlowBranching.Merge): Avoid foreach on
+       arraylist.
+
+       * expression.cs (Invocation.OverloadResolve): Avoid foreach on
+       arraylists, use for loop with bounds.
+
+       The above three changes give us a 0.071 second performance
+       improvement out of 3.294 seconds down to 3.223.  On my machine
+       the above changes reduced the memory usage by 1,387 KB during
+       compiler bootstrap.
+
+       * cs-parser.jay (QualifiedIdentifier): New class used to represent
+       QualifiedIdentifiers.  Before we created a new string through
+       concatenation, and mostly later on, the result would be
+       manipulated by DecomposeQI through string manipulation.
+
+       This reduced the compiler memory usage for bootstrapping from
+       59380 KB to 59007 KB on my machine, 373 KB, and also reduced the
+       compile times in 0.05 seconds.
+
+2003-11-28  Dick Porter  <dick@ximian.com>
+
+       * support.cs: Do string compares with the Invariant culture.
+
+       * rootcontext.cs: 
+       * gen-treedump.cs: 
+       * expression.cs: 
+       * driver.cs: 
+       * decl.cs: 
+       * codegen.cs: 
+       * class.cs: Use the char forms of IndexOf and LastIndexOf, so that
+       the comparison is done with the Invariant culture.
+
+2003-11-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Foreach.TryType): Use DeclaredOnly to find the
+       GetEnumerator method.
+
+       (ProbeCollectionType): Iterate starting at the most specific type
+       upwards looking for a GetEnumerator
+
+       * expression.cs: Shift count can be up to 31 for int/uint and 63
+       for long/ulong.
+
+2003-11-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Block.LookupLabel): Also look for the label on the
+       children blocks.  Use a hash table to keep track of visited
+       nodes. 
+
+       * cfold.cs (IntConstant to UIntConstant mapping): Only return if
+       we actually did transform the other operand, otherwise fall back
+       to the common codepath that casts to long.
+
+       * cs-tokenizer.cs: Use the same code pattern as the int case.
+       Maybe I should do the parsing myself, and avoid depending on the
+       Parse routines to get this done.
+
+2003-11-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Apply fix from l_m@pacbell.net (Laurent Morichetti),  
+       which fixes bug 51347.  This time test it.
+
+       * expression.cs: Make TypeOfVoid derive from TypeOf, so code in
+       attributes for example can not tell the difference between these.
+       The difference was only a syntax feature of the language. 
+
+       * attribute.cs: Apply attributes to delegates.
+
+       * delegate.cs: Call the apply attributes method.
+
+2003-11-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * convert.cs (TryImplicitIntConversion): One line bug fix: we were
+       comparing 0 vs Byte.MinValue, not the value
+
+       (ImplicitConversionRequired): When reporting a conversion error,
+       use error 31 to print out the constant error instead of the
+       simpler 29.
+
+       * expression.cs: Apply fix from l_m@pacbell.net (Laurent Morichetti),  
+       which fixes bug 51347.
+
+2003-11-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Applied patch from gert.driesen@pandora.be (Gert Driesen) 
+       which fixes the -warnaserror command line option.
+
+2003-11-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * cfold.cs (DoNumericPromotions): During constant folding of
+       additions on UIntConstant, special case intconstants with
+       IntConstants like we do on the expression binary operator. 
+
+2003-11-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * convert.cs (ImplicitReferenceConversion): We were missing a case
+       (System.Enum are not value types or class types, so we need to
+       classify them separatedly).
+
+       * driver.cs: We do not support error 2007.
+
+2003-11-12 Jackson Harper <jackson@ximian.com>
+
+       * driver.cs: Use corlib.dll or mscorlib.dll when looking up the
+       system directory. Also use the full file name so users can
+       libraries names mscorlib-o-tron.dll in a non system dir.
+       
+2004-01-04  David Sheldon <dave-mono@earth.li>
+
+       * expression.cs: Added matching ")" to error message for CS0077.
+
+2003-12-19  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.IsEqualGenericType): New public
+       static method; see documentation in the method.
+       (TypeManager.IsSubclassOrNestedChild): Allow IsEqualGenericType().
+
+       * convert.cs (Convert.ImplicitReferenceConversion,
+       Convert.ImplicitReferenceConversionExists): Add support for
+       generic type declarations; see gen-36.cs.
+
+2003-12-19  Martin Baulig  <martin@ximian.com>
+
+       * pending.cs (Pending.InterfaceMethod): Use
+       `Type.IsAssignableFrom()' instead of `=='.
+
+2003-12-18  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.AsAccessible): Check for array, pointer and
+       byref types first.
+
+       * convert.cs (Convert.ImplicitStandardConversionExists): Use
+       `expr_type.Equals (target_type)' instead of `=='.
+
+2003-12-08  Martin Baulig  <martin@ximian.com>
+
+       * generics.cs (Constraints.Types): Removed.
+       (Constraints.Resolve): Just resolve everything to TypeExpr's, not
+       to Type's.
+       (Constraints.ResolveTypes): New public method; resolves the
+       TypeExpr's to Type's.
+       (TypeParameter.Define): TypeBuilder.DefineGenericParameter() no
+       longer takes the constraints.
+       (TypeParameter.DefineMethod): Likewise.
+       (TypeParameter.DefineType): New public method.  Calls
+       `TypeBuilder/MethodBuilder.SetGenericParameterConstraints()' to set
+       the constraints.
+
+2003-12-08  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs (Convert.ImplicitConversionStandard): Use
+       `expr_type.Equals (target_type)' instead of `=='.
+
+2003-12-08  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.GetReferenceType): Call
+       `Type.MakeByRefType ()'.
+
+2003-12-08  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay, cs-tokenizer.cs: `where' is not a keyword, it
+       just has some special meaning in some situations.  For instance,
+       it is allowed to use `where' as the name of a variable etc.
+
+2003-12-04  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (ComposedCast.DoResolveAsTypeStep): Use
+       `Type.MakeArrayType()' for array types.
+
+2003-11-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Invocation.VerifyArgumentsCompat): Remove
+       debugging message.
+
+       (SizeOf.DoResolve): assign the `type_queried' field.  This gets
+       corlib to compile.
+
+2003-11-16  Martin Baulig  <martin@ximian.com>
+
+       * codegen.cs (EmitContext.IsGeneric): Removed.
+
+       * ecore.cs (SimpleName.ResolveAsTypeStep): Always call
+       ResolveGeneric() on the DeclSpace.
+
+2003-11-16  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (TypeArguments.Resolve):
+       `Expression.ResolveAsTypeTerminal()' returns a TypeExpr; call
+       `ResolveType()' on it to get the Type.
+
+2003-11-15  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.GetInterfaces): Override this.
+
+2003-11-14  Martin Baulig  <martin@ximian.com>
+
+       * interface.cs (Interface.DefineType): Define all type parameters
+       before adding the interfaces we inherit.
+
+2003-11-11  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.ResolveType): Always call
+       `gt.BindGenericParameters (atypes)'; also if `args.HasTypeArguments'.
+
+2003-11-10  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.ResolveExpressionTypes): Removed.
+       (TypeManager.InitCoreTypes): Initialize them here, but instead of
+       calling `ResolveType()' on them, directly assign their `Type'.
+
+2003-11-08  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType): Override `IsClass' etc.
+
+2003-11-08  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.GetClassBases): Use TypeExpr's for the
+       return value and the `out parent' parameter.
+       (TypeContainer.DefineType): Moved the CS0644 check into
+       GetClassBases().  Don't pass the interface types to the
+       `builder.DefineType()'/`builder.DefineNestedType()', but resolve
+       them later and then call `TypeBuilder.AddInterfaceImplementation()'.
+
+       * ecore.cs (TypeExpr.IsAttribute): New property.
+       (TypeExpr.GetInterfaces): New method.
+
+       * interface.cs (Interface.GetInterfaceTypeByName): Return a
+       TypeExpr instead of a Type.
+       (Interface.GetInterfaceBases): Return TypeExpr's instead of Type's.
+       (Interface.DefineType): Don't pass the interface types to the
+       `builder.Definetype()'/`builder.DefineNestedType()', but resolve
+       them later and then call `TypeBulider.AddInterfaceImplementation()'.
+
+       * typemanager.cs (TypeManager.AddUserType): Take a `TypeExpr[]'
+       instead of a `Type[]'.
+       (TypeManager.RegisterBuilder): Likewise.
+       (TypeManager.AddUserInterface): Likewise.
+       (TypeManager.ExpandInterfaces): Take a `Type[]' instead of a
+       `Type[]' and also return a `TypeExpr[]'.
+       (TypeManager.GetInterfaces): Return a `TypeExpr[]'.
+
+2003-11-08  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.ResolveTypeExpr): Return a TypeExpr, not an
+       Expression.     
+
+2003-11-08  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.GetTypeResolveEmitContext): Call
+       TypeManager.ResolveExpressionTypes().
+
+       * ecore.cs (Expression.ResolveAsTypeTerminal): Return a TypeExpr
+       instead of an Expression.
+       (TypeExpr): This is now an abstract base class for `TypeExpression'.
+       (TypeExpression): New public class; formerly known as `TypeExpr'.
+
+       * expression.cs (ComposedCast): Derive from TypeExpr.
+
+       * typemanager.cs (TypeManager.system_*_expr): These are now
+       TypExpr's instead of Expression's.
+       (TypeManager.ResolveExpressionTypes): New public static function;
+       called from DeclSpace.GetTypeResolveEmitContext() to resolve all
+       of them.        
+
+2003-11-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (New.DoResolve): Do not dereference value that
+       might be a null return.
+
+       * statement.cs (Block.EmitMeta): Use the Const.ChangeType to make
+       sure that the constant value has the right type.  Fixes an
+       unreported bug, similar to 50425.
+
+       * const.cs (Const.LookupConstantValue): Call
+       ImplicitStandardConversionExists before doing a conversion to
+       avoid havng the TypeManager.ChangeType do conversions.
+
+       Reduced the number of casts used
+
+       (Const.ChangeType): New routine to enable reuse of the constant
+       type changing code from statement.
+
+       * typemanager.cs (ChangeType): Move common initialization to
+       static global variables.
+
+       Fixes #50425.
+
+       * convert.cs (ImplicitReferenceConversion): Somehow we allowed
+       every value type to go through, even if it was void.  Fix that. 
+
+       * cs-tokenizer.cs: Use is_identifier_start_character on the start
+       character of the define, and the is_identifier_part_character for
+       the rest of the string.
+
+2003-11-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (UnaryMutator.EmitCode): When I updated
+       LocalVariableReference.DoResolve, I overdid it, and dropped an
+       optimization done on local variable references.
+
+2003-11-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs: Convert the return from Ldlen into an int.
+
+2003-10-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * decl.cs (DeclSpace.GetAccessLevel): Handle NotPublic case for
+       the accessibility, this is a special case for toplevel non-public
+       classes (internal for instance).
+
+2003-10-20  Nick Drochak <ndrochak@gol.com>
+
+       * ecore.cs: Fix typo and build.  Needed another right paren.
+
+2003-10-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs: Applied fix from Ben Maurer.   We were handling in the
+       `internal' case regular and protected, but not allowing protected
+       to be evaluated later.  Bug 49840
+
+2003-10-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Switch.TableSwitchEmit): Compare the upper bound
+       to kb.Nlast, and not the kb.nFirst to isolate the switch
+       statement.
+
+       Extract the underlying type, so enumerations of long/ulong are
+       treated like long/ulong.
+
+2003-10-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (New): Overload the meaning of RequestedType to
+       track the possible creation of the NewDelegate type, since
+       DoResolve is invoked more than once for new constructors on field
+       initialization.
+
+       See bugs: #48800 and #37014
+
+       * cs-parser.jay (declare_local_constants): Take an arraylist
+       instead of a single constant.
+
+       (local_constant_declaration): It should take a
+       constant_declarators, not a constant_declarator.  Fixes 49487
+
+       * convert.cs: Fix error report.
+
+2003-10-13 Jackson Harper <jackson@ximian.com>
+
+       * typemanager.cs (TypeToCoreType): Add float and double this fixes
+       bug #49611
+       
+2003-11-03  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (ArrayAccess.GetStoreOpcode): Added
+       `out bool has_type_arg'; if set, we need to pass the type to
+       ig.Emit().
+       (ArrayAccess.GetStoreOpcode, ArrayAccess.EmitLoadOpcode): Use
+       Stelem_Any/Ldelem_Any for generic parameters.   
+
+2003-11-02  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.EmitCall): Use
+       `TypeManager.IsValueType()' to check whether it's a value type.
+       Don't set `struct_call' when calling a method on a type parameter.
+
+2003-11-02  Martin Baulig  <martin@ximian.com>
+
+       * generics.cs (ConstructedType.Resolve): Renamed to ResolveType()
+       and removed the TypeBuilder argument.
+
+       * typemanager.cs (TypeManager.IsValueType): Return
+       `t.IsGenericParameter || t.IsValueType'.
+
+2003-10-25  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.ResolveType): If we're a ConstructedType,
+       call ConstructedType.Resolve() on it.
+
+       * generic.cs (ConstructedType.Resolve): Set `type' on success.
+
+2003-10-25  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.GetClassBases): Changed
+       `out Type parent' into `out TypeExpr parent'.  Moved CS0644 and
+       CS8214 reporting here.
+       (TypeContainer.DefineType): GetClassBases() gives us a `TypeExpr'
+       instead of a `Type' for our parent.  In case of a recursive
+       declaration (see tests/gen-23.cs for an example), our parent is a
+       ConstructedType and it doesn't have its type set.  So, first
+       create our own TypeBuilder, then call constructed.Resolve() to get
+       the parent's type and finally TypeBuilder.SetParent() it.
+
+       * ecore.cs (TypeExpr.Name): New public virtual property.
+
+       * generic.cs
+       (ConstructedType): We're now a TypeExpr and not just an Expression.
+       (ConstructedType.ResolveAsTypeStep): Don't resolve our type
+       arguments here; this is done later.
+       (ConstructedType.Resolve): New public method to resolve the type
+       arguments and bind them.
+
+2003-10-21  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs: Use `TypeManager.IsValueType' instead of
+       'type.IsValueType' everywhere.
+
+       * typemanager.cs (TypeManager.IsValueType): Return true for type
+       parameters.  The reason for this is that we need to box a type
+       parameter when converting it to a reference type.
+
+       * cs-parser.jay: Added support for default value expressions.
+
+       * generics.cs (DefaultValueExpression): New public class.       
+
+2003-10-17  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (Constraints.Resolve): Take a DecpSpace instead of a
+       TypeContainer so we can also use this for Interfaces.
+       (TypeParameter.Resolve): Likewise.
+
+       * interface.cs (Interface.DefineType): Added support for generic
+       interfaces.
+
+       * cs-parser.jay: Added support for generic structs and interfaces.
+
+2003-10-17  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (GenericMemberAccess.DoResolve): We can now actually
+       call generic methods :-)
+
+2003-10-16  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay (namespace_or_type_name): Only create a
+       GenericMemberAccess if we actually have type arguments.
+
+2003-10-13  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Method.Define): If we're a generic method, call
+       TypeBuilder.DefineGenericMethod () before resolving
+       the parameters.
+       (MethodData): Added .ctor which takes an additional MethodBuilder
+       argument; this is used for generic methods.
+       (MethodData.Define): Call `builder.SetGenericMethodSignature()' if
+       we already have a MethodBuilder.
+
+2003-10-10  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Method): Added .ctor which takes a `GenericMethod'
+       instead of a `DeclSpace'.  This is used for generic methods.
+
+       * cs-parser.jay (method_header): Added support for generic
+       methods; create a `GenericMethod' instance and pass it to the
+       `Method's .ctor; it'll be used as the `DeclSpace' to lookup
+       parameters and locals.
+
+       * decl.cs (DeclSpace.SetParameterInfo): Removed Location argument
+       since we already have the location.  Check whether we're a generic
+       type declaration or a generic method and create the correct type
+       parameter.
+
+       * generic.cs (TypeParameter.DefineMethod): New public method.
+       (GenericMethod): New public class; derives from DeclSpace and is
+       used for generic methods.       
+
+2003-10-09  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodCore): Added additional `DeclSpace ds' argument
+       to the .ctor.
+       (MethodCore.DoDefineParameters): Removed the TypeContainer
+       argument; use the DeclSpace which was passed to the .ctor instead.
+       (MethodCore.CheckParameter): Take a DeclSpace instead of a
+       TypeContainer; we only need a DeclSpace here.
+
+2003-10-09  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodData): Added additional `DeclSpace ds' argument
+       to the .ctor.
+       (MethodData.Define, MethodData.Emit): Pass the `ds' to the
+       EmitContext's .ctor.    
+
+2003-10-09  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.AsAccessible): Moved here from TypeContainer.
+       (AccessLevel, CheckAccessLevel, GetAccessLevel): They're used by
+       AsAccessible(), moved them as well.
+
+       * class.cs (TypeContainer.AsAccessible): Moved to DeclSpace.
+
+2003-10-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Binary.Emit.GreatherThanOrEqual): Fix the code
+       generation for >=, as spotted by Paolo, bug 48679.  
+       Patch from David Waite.
+
+       * cs-tokenizer.cs: Add handling for #pragma.
+
+       * cs-parser.jay: Allow for both yield and yield return in the
+       syntax.  The anti-cobolization of C# fight will go on!
+
+       * class.cs (TypeBuilder.DefineType): Catch error condition here
+       (Parent.DefineType erroring out and returning null).
+
+       * expression.cs (ArrayCreation.EmitDynamicInitializers): When
+       coping with enumerations variables, we were mistakenly processing
+       them as a regular value type instead of built-in types.  Fixes the
+       bug #48063
+
+       * typemanager.cs (IsBuiltinOrEnum): New method.
+
+2003-09-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Upgrade: yield now needs the return clause.
+
+2003-10-08  Atsushi Enomoto <ginga@kit.hi-ho.ne.jp>
+
+       * cs-parser.jay : Renamed yyName to yyNames related to jay.
+
+2003-09-29  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.GetMethodFlags): Added support for
+       inflated generic methods.
+
+       * generics.cs (ConstructedType): Distinguish between open and
+       closed constructed types; correctly resolve the arguments.
+
+2003-09-22  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.ResolveAsTypeCheck): Check whether
+       all type arguments meet their constraints.
+
+2003-09-19  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCache.SetupCacheForInterface): Take a
+       `MemberCache parent' argument.  Normally, an interface doesn't
+       have a parent type except System.Object, but we use this in gmcs
+       for generic type parameters.
+
+2003-09-18  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeHandle.ctor): Set `IsInterface' solely based
+       on `type.IsInterface'; don't check whether the type has a parent
+       to determine whether it's an interface.
+
+2003-09-17  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.ToString): Always use `name' as the
+       type name.
+
+2003-09-15  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay: Fix grammar wrt. type_parameter_constraints.
+
+       * generic.cs (Constraints.Resolve): New public method; this is
+       called to resolve the constraint types and to check whether all
+       the constraints are correct.
+       (Constraints.Types): New public property.
+       (TypeParameter.Resolve): New public method; resolves all the
+       type's constraints.
+
+       * class.cs (TypeContainer.DefineType): Call
+       TypeParameter.Resolve() before actually defining the type.
+
+2003-09-15  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.DefineType): Added an error flag to
+       avoid reporting duplicate CS0146's ("class definition is
+       circular.").
+
+       * driver.cs (Driver.MainDriver): Abort if
+       RootContext.ResolveTree() reported any errors.
+
+2003-09-07  Martin Baulig  <martin@ximian.com>
+
+       * report.cs (Error, Warning): Added overloaded versions which take
+       a `params object[] args' and call String.Format().
+
+2003-09-07  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace..ctor): Don't call
+       NamespaceEntry.DefineName() here; do it in RecordDecl() which is
+       called from Tree.RecordDecl().  Fixes the CS0101 reporting.
+       (DeclSpace.RecordDecl): New method.
+
+       * tree.cs (Tree.RecordDecl): Call ds.RecordDecl().
+
+2003-09-02  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (CheckAttributeTarget): Ensure that we allow return
+       value attributes to be applied to ParameterBuilders.
+
+       * class.cs (MethodCore.LabelParameters): Make static and more
+       generic so that it can be used from other places - like interface
+       methods, for instance.
+
+       * interface.cs (Interface.Emit): Call LabelParameters before
+       emitting attributes on the InterfaceMethod.
+
+2003-09-07  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.ResolveAsTypeStep): Report a CS8217
+       if the number of type parameters doesn't match.
+
+2003-09-04  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (ComposedCast.ResolveAsTypeStep): Added support
+       for arrays of generic type params (ie. `!0[]').
+
+2003-09-04  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.AsAccessible): Ignore generic parameters
+       for the moment.
+
+2003-09-04  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.LookupGeneric): New method.
+       (DeclSpace.CheckAccessLevel): Ignore generic parameters for the
+       moment.
+
+       * generic.cs (TypeParameterExpr): Take a TypeParameter as
+       argument, not just a string.
+       (TypeParameter.Define): New public method; this is called to
+       actually define the generic parameter; after this, you can use the
+       new `Type' property to get the type.
+
+2003-09-04  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.SetParameterInfo): The `constraints' argument
+       is now an ArrayList; initialize the result of the `TypeParameters'
+       property here.
+       (DeclSpace.GetGenericData): Removed.
+       (DeclSpace.LookupGeneric): Temporarily removed; we need to
+       implement this in a different way.
+       (DeclSpace.GetTypeParameters): Removed; there's now a
+       `TypeParameters' property.
+       (DeclSpace.TypeParameters): New public property.
+
+       * generic.cs (Constraints): Make this class public.
+       (TypeParameter): New public class.
+
+2003-09-04  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (DeclSpace.GetTypeParameters): New method to return the
+       generic parameters.
+
+       * class.cs (TypeContainer.DefineType): Call
+       TypeBuilder.DefineGenericParameter () on all generic parameters if
+       this is a generic type.
+
+2003-08-28  Martin Baulig  <martin@ximian.com>
+
+       * sample-stack.il: Compile this with ilasm: "ilasm /dll
+       sample-stack.il".
+
+       * sample-hello.cs: Compile this with gmcs: "gmcs
+       /r:sample-stack.dll sample-hello.cs".
+
+2003-08-28  Martin Baulig  <martin@ximian.com>
+
+       * generic.cs (ConstructedType.ResolveAsTypeStep): Actually bind
+       the parameters to the generic type.
+
+2003-08-28  Martin Baulig  <martin@ximian.com>
+
+       * cs-tokenizer.cs (parse_less_than): Also allow all builtin types.
+
+2003-08-28  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay (opt_type_argument_list): Use
+       `OP_GENERICS_LT type_arguments OP_GENERICS_GT'.
+       (primary_expression): Replace `qualified_identifier' with `type_name'.
+       (type_parameter_list): Use `OP_GENERICS_LT type_parameters OP_GENERICS_GT'.
+
+       * cs-tokenizer.cs (is_punct): When reading a `<', invoke a custom
+       parser to check whether it is syntactically a type parameter list;
+       return OP_GENERICS_LT/OP_GENERICS_GT instead of OP_LT/OP_GT in
+       this case.
+
+2003-08-26  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Look for members before
+       resolving aliases; fixes #47927.
+
+2003-08-26  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Using.DoResolve): This is internally emitting a
+       try/finally clause, so we need to set ec.NeedExplicitReturn if we
+       do not always return.  Fixes #47681.
+
+2003-08-26  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCore): Moved WarningNotHiding(),
+       Error_CannotChangeAccessModifiers() and CheckMethodAgainstBase()
+       into MemberBase.
+       (AdditionResult): Make this nested in DeclSpace.
+       (DeclSpace.ctor): The .ctor now takes an additional NamespaceEntry
+       argument; call NamespaceEntry.Define() unless we're nested in a
+       class or struct.
+
+       * namespace.cs (Namespace.DefineName): New public function.  This
+       is called from DeclSpace's .ctor to add 
+       (Namespace.Lookup): Include DeclSpaces in the lookup.
+
+       * class.cs (Operator): Derive from MemberBase, not MemberCore.
+
+       * const.cs (Const): Derive from MemberBase, not MemberCore.     
+
+2003-08-25  Martin Baulig  <martin@ximian.com>
+
+       * convert.cs (Convert.ExplicitReferenceConversion): When
+       converting from an interface type to a class, unbox if the target
+       type is a struct type.  Fixes #47822.
+
+2003-08-24  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * typemanager.cs: fixed the values of MethodFlags. Closes #47855 and
+       #47854.
+
+2003-08-22  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeManager.DefineType): When defining a nested type,
+       call DefineType() on our parent; fixes #47801.
+
+2003-08-22  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodData.Define): While checking if a method is an
+       interface implementation, improve the test a bit more to fix #47654.
+
+2003-08-22  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Probe.DoResolve): Check whether `expr' resolved
+       correctly; fixes #47722.
+
+2003-08-22  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (UnaryMutator.ResolveVariable): If the target is a
+       LocalVariableReference, ensure it's not read-only.  Fixes #47536.
+
+       * statement.cs (Fixed.DoResolve): Make all variables read-only. 
+
+2003-08-22  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (FieldExpr.DoResolveLValue): Static read-only fields
+       can only be assigned in static constructors.  Fixes #47161.
+
+2003-08-22  Martin Baulig  <martin@ximian.com>
+
+       Rewrote and improved the flow analysis code.
+
+       * flowbranching.cs (FlowBranching): Make this class abstract.
+       (FlowBranching.CreateBranching): New static function to create a
+       new flow branching.
+       (FlowBranchingBlock, FlowBranchingException): New classes.
+       (FlowBranching.UsageVector.Type): New public readonly field.
+       (FlowBranching.UsageVector.Breaks): Removed the setter.
+       (FlowBranching.UsageVector.Returns): Removed the setter.
+       (FlowBranching.UsageVector): Added Break(), Return(),
+       NeverReachable() and Throw() methods to modify the reachability.
+       (FlowBranching.UsageVector.MergeChildren): Removed, this is now
+       done by FlowBranching.Merge().
+       (FlowBranching.UsageVector.MergeChild): New method; merges the
+       merge result into the current vector.
+       (FlowBranching.Merge): New abstract method to merge a branching.
+
+2003-08-12  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Indirection.CacheTemporaries): Create the
+       LocalTemporary with the pointer type, not its element type.
+
+2003-08-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: FIRST_KEYWORD, LAST_KEYWORD: used to know if a
+       token was a keyword or not.
+
+       Add `error' options where an IDENTIFIER was expected;  Provide
+       CheckToken and CheckIdentifierToken convenience error reporting
+       functions. 
+
+       Do not use `DeclSpace.Namespace', use `DeclSpace.NamespaceEntry'.
+
+       * decl.cs: Rename `NamespaceEntry Namespace' public field into
+       NameSpaceEntry NameSpaceEntry.
+
+       (LookupInterfaceOrClass): Avoid creating a full qualified name
+       from namespace and name: avoid doing lookups when we know the
+       namespace is non-existant.   Use new Tree.LookupByNamespace which
+       looks up DeclSpaces based on their namespace, name pair.
+
+       * driver.cs: Provide a new `parser verbose' to display the
+       exception thrown during parsing.  This is turned off by default
+       now, so the output of a failure from mcs is more graceful.
+
+       * namespace.cs: Track all the namespaces defined in a hashtable
+       for quick lookup.
+
+       (IsNamespace): New method
+
+2003-08-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * namespace.cs: Remove redundant call;  Avoid using MakeFQN when
+       we know that we need to concatenate (full typename can never be
+       null). 
+
+       * class.cs: ditto.
+
+       * statement.cs: Use a bitfield;  Do not initialize to null things
+       which are done by the constructor by default.
+
+       * cs-parser.jay: bug fix, parameter was 4, not 3.
+
+       * expression.cs: Just use the property;
+
+       * statement.cs: No need for GetVariableInfo method.
+
+2003-08-08  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowReturns): This is now nested in the
+       `FlowBranching' class.
+       (MyBitVector): Moved this here from statement.cs.
+       (FlowBranching.SiblingType): New enum type.
+       (FlowBranching.CreateSibling): Added `SiblingType' argument.
+
+2003-08-07  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs (FlowBranchingType): This is now nested in the
+       `FlowBranching' class and called `BranchingType'.
+
+2003-08-07  Martin Baulig  <martin@ximian.com>
+
+       * flowanalysis.cs: Moved all the control flow analysis code into
+       its own file.
+
+2003-08-07  Martin Baulig  <martin@ximian.com>
+
+       * assign.cs (Assign.DoResolve): `target' must either be an
+       IAssignMethod or an EventAccess; report a CS0131 otherwise.  Fixes
+       #37319.
+
+2003-08-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (BinaryMethod): This kind of expression is created by the
+       Binary class if it determines that the operator has to be handled
+       by a method.
+
+       (BinaryDelegate): This kind of expression is created if we are
+       dealing with a + or - operator on delegates.
+
+       (Binary): remove method, argumetns, and DelegateOperator: when
+       dealing with methods, 
+
+       * ecore.cs (EventExpr.EmitAddOrRemove): Update to new layout.
+
+       * statement.cs (Block): use bitfields for the three extra booleans
+       we had in use.   Remove unused topblock parameter.
+
+       * codegen.cs: Remove unecessary argument to Block.EmitTopBlock
+
+       * assign.cs: Drop extra unneeded tests.
+
+2003-08-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * iterators.cs (Mapvariable): provide a mechanism to use prefixes.
+
+       * statement.cs (Foreach): Use VariableStorage instead of
+       LocalBuilders.   
+
+       * codegen.cs (VariableStorage): New class used by clients that
+       require a variable stored: locals or fields for variables that
+       need to live across yield.
+
+       Maybe provide a convenience api for EmitThis+EmitLoad?
+
+       (GetTemporaryLocal, FreeTemporaryLocal): Recycle
+       these bad boys.
+
+2003-08-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs (RemapLocal, RemapLocalLValue, RemapParameter,
+       RemapParameterLValue): New methods that are used to turn a
+       precomputed FieldInfo into an expression like this:
+
+               instance.FieldInfo
+
+       The idea is to use this instead of making LocalVariableReference
+       have more than one meaning.
+
+       * cs-parser.jay: Add error production to BASE.
+
+       * ecore.cs: Deal with TypeManager.GetField returning null, which
+       is now a valid return value.
+
+       (FieldExprNoAddress): New expression for Fields whose address can
+       not be taken.
+
+       * expression.cs (LocalVariableReference): During the resolve
+       phases, create new expressions if we are in a remapping context.
+       Remove code that dealt with remapping here.
+
+       (ParameterReference): same.
+
+       (ProxyInstance): New expression, like the `This' expression, but
+       it is born fully resolved.  We know what we are doing, so remove
+       the errors that are targeted to user-provided uses of `this'.
+
+       * statement.cs (Foreach): our variable is now stored as an
+       Expression;  During resolution, follow the protocol, dont just
+       assume it will return this.
+
+2003-08-06  Martin Baulig  <martin@ximian.com>
+
+       * support.cs (SeekableStreamReader.cs): New public class.
+
+       * cs-tokenizer.cs, cs-parser.jay, driver.cs: Use the new
+       SeekableStreamReader instead of the normal StreamReader.
+
+2003-08-04  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay (CLOSE_PARENS_CAST, CLOSE_PARENS_NO_CAST,
+       CLOSE_PARENS_OPEN_PARENS, CLOSE_PARENS_MINUS): New tokens to
+       deambiguate casts and delegate invocations.
+       (parenthesized_expression): Use the new tokens to ensure this is
+       not a cast of method invocation.
+
+       * cs-tokenizer.cs (is_punct): Return one of the new special tokens
+       when reading a `)' and Deambiguate_CloseParens () was previously
+       called.
+
+       * expression.cs (ParenthesizedExpression): New class.  This is
+       just used for the CS0075 test.
+       (Binary.DoResolve): Check for CS0075.   
+
+2003-07-29  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Invocation.MakeUnionSet): Patch from Lluis
+       Sanchez : use TypeManager.ArrayContainsMethod instead of a direct
+       reference comparison.
+
+       (TypeManager.ArrayContainsMethod): When we have a MethodInfo, also
+       examine the ReturnType for equality - this is necessary in the
+       cases of implicit and explicit operators whose signature also
+       includes the return type.
+
+2003-07-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * namespace.cs: Cache the result of the namespace computation,
+       instead of computing it every time.
+
+2003-07-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * decl.cs: Use a global arraylist that we reuse over invocations
+       to avoid excesive memory consumption.  Reduces memory usage on an
+       mcs compile by one meg (45 average).
+
+       * typemanager.cs (LookupTypeReflection): In .NET pointers are
+       private, work around that.
+
+2003-07-23  Miguel de Icaza  <miguel@ximian.com>
+
+       * literal.cs (IntLiteral): Define Zero and One static literals. 
+
+       * cs-parser.jay (integer_literal): use static literals to reduce
+       memory usage for the most used literals (0, 1 and -1).  211kb
+       reduced in memory usage.
+
+       Replace all calls to `new ArrayList' with `new
+       ArrayList(4)' which is a good average number for most allocations,
+       and also requires only 16 bytes of memory for its buffer by
+       default. 
+
+       This reduced MCS memory usage in seven megabytes for the RSS after
+       bootstrapping.
+
+2003-07-28  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Invocation.OverloadResolve): Fix the algorithm to
+       handle params methods the correct way by forming only one
+       applicable set with params and normal methods in them. Earlier we
+       were looking at params methods only if we found no normal methods
+       which was not the correct thing to do.
+
+       (Invocation.BetterFunction): Take separate arguments indicating
+       when candidate and the best method are params methods in their
+       expanded form.
+
+       This fixes bugs #43367 and #46199.
+
+       * attribute.cs: Documentation updates.
+
+       (CheckAttribute): Rename to CheckAttributeTarget.
+       (GetValidPlaces): Rename to GetValidTargets.
+
+       * expression.cs (Invocation.IsParamsMethodApplicable): Fix trivial
+       bug - use Convert.ImplicitConversion, not ImplicitUserConversion!
+
+       Fixes bug #44468.
+
+2003-07-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs: Compute IsGeneric correctly.
+
+       * cs-parser.jay: Introduce OP_GENERIC_LT for the grammar ambiguity
+       resolution. 
+
+       Bring back (temporarily) OP_LEFT_SHIFT, OP_RIGHT_SHIFT,
+       OP_SHIFT_RIGHT_ASSIGN, OP_SHIFT_LEFT_ASSIGN.  There were too many
+       regressions, and I was chasing more bugs than I required.
+
+       * interface.cs: Use expressions for base type names (like classes
+       and structs have been doing for a while now), and resolve that.
+       This patch should probably go into head as well.
+
+       This makes it one less user of FindType.
+
+2003-07-24  Miguel de Icaza  <miguel@ximian.com>
+
+       This compiler can not self host currently.  Need to fix that.
+       
+       * Makefile: compile to `gmcs.exe'
+
+       * driver.cs: Turn on v2 by default on gmcs.
+
+       * generic.cs (ConstructedType): Does no longer take a container
+       type argument;  That will be taken care of later.
+
+       (ConstructedType.DoResolve, ConstructedType.ResolveAsTypeStep):
+       Use SimpleName to resolve for now, so we can continue the work on
+       the parser, until we get Type.GetType that understands generics.
+
+       (ConstructedType.ToString): Implement
+
+       (TypeArguments.Resolve): Resolve the child expressions as types. 
+       
+       * cs-parser.jay: Rename interface_constraints to
+       type_parameter_constraints
+
+       (namespace_or_type_name): Only use constructed types for the basic
+       construction, we will deal with identifier<...> later.
+
+       (type/type_name): No longer call DecomposeQI, as
+       namespace_or_type_name is always decoded now.
+       
+2003-07-22  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Invocation.OverloadResolve): Follow the spec more
+       closely: we eliminate methods in base types when we have an
+       applicable method in a top-level type.
+
+        Please see section 14.5.5.1 for an exact description of what goes
+       on. 
+
+       This fixes bug #45127 and a host of other related to corlib compilation.
+
+        * ecore.cs (MethodGroupExpr.DeclaringType): The element in the
+       array is the method corresponding to the top-level type (this is
+       because of the changes made to icall.c) so we change this
+       accordingly.
+
+       (MethodGroupExpr.Name): This too.
+
+       * typemanager.cs (GetElementType): New method which does the right
+       thing when compiling corlib. 
+
+       * everywhere: Make use of the above in the relevant places.
+
+2003-07-22  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay (invocation_expression): Moved
+       `OPEN_PARENS expression CLOSE_PARENS unary_expression' here from
+       `cast_expression', but create a InvocationOrCast which later
+       resolves to either an Invocation or a Cast.
+
+       * ecore.cs (ExpressionStatement.ResolveStatement): New virtual
+       method; call this before EmitStatement() to make sure that this
+       expression can be used as a statement.
+
+       * expression.cs (InvocationOrCast): New class; resolves to either
+       an Invocation or a Cast.
+
+       * statement.cs (StatementExpression): Call ResolveStatement() on
+       the ExpressionStatement before emitting it.
+
+2003-07-21  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.VerifyArgumentsCompat): Check whether
+       `ref' and `out' attributes match; fixes #46220.
+       (MemberAccess.ResolveMemberAccess): You can't reference a type
+       through an expression; fixes #33180.
+       (Indexers.GetIndexersForType): Don't return the indexers from
+       interfaces the class implements; fixes #46502.
+
+2003-07-21  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (TypeContainer.CheckPairedOperators): Added CS0660 and
+       CS0661 checks; fixes bug #30442.
+
+2003-07-21  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (AdditionResult): Added `Error'.
+
+       * enum.cs (AddEnumMember): Report a CS0076 if name is `value__'.
+
+       * typemanager.cs (TypeManager.ChangeType): Catch exceptions; makes
+       cs0031.cs actually work.
+
+ 2003-07-20  Miguel de Icaza  <miguel@ximian.com>
+       * cs-parser.jay (namespace_name): do not use
+       namespace_or_type_name, use qualified_identifier, because
+       namespace_or_type_name will soon return a composed expression
+       instead of a string.
+       (namespace_or_type_name): Instead of returning a string, now this
+       production returns an expression.
+       * codegen.cs (EmitContext): Setup IsGeneric property based on
+       whether our DeclSpace is generic, our the method is generic.
+       * modifier.cs (Modifiers.METHOD_GENERIC): New definition, use if
+       the method is generic.
+       * cs-parser.jay (type_arguments, opt_type_argument_list,
+       type_parameters, type_parameter_list, opt_type_parameter_list,
+       type_parameter,, opt_type_parameter_constraints_clauses,
+       type_parameter_constraints_clauses,
+       type_parameter_constraint_clause, type_parameter_constraint,
+       interface_constraints): Add new production
+       * decl.cs (DeclSpace): IsGeneric, flag to track whether this
+       DeclSpace is generic or not.
+       (DeclSpace.SetParameterInfo): New routine, used to set the
+       parameter info for a type.
+       (DeclSpace.LookupGeneric): Lookups a name, and if it is a generic,
+       returns a GenericTypeExpr
+       * ecore.cs (SimpleName.ResolveAsTypeStep): If our container is
+       generic, lookup the generic argument.
+       * attribute.cs: Do not allow TypeParameterExpressions in
+       Attributes.
+       * class.cs: Do not allow the Main method to be defined in a
+       Generic container.
+       * expression.cs (SizeOf): Do not allow generic types to be used as
+       arguments to sizeof.
+       * typemanager.cs (IsGeneric): Wrapper for Reflection when we have
+       it: whether a type is generic or not.  Only works for types we are
+       currently building for now.
+       
+2003-07-20  Martin Baulig  <martin@ximian.com>
+
+       * namespace.cs: Fixed that bug which caused a crash when compiling
+       the debugger's GUI.
+
+2003-07-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (LookupTypeReflection): Never expose types which
+       are NotPublic, NestedPrivate, NestedAssembly, or
+       NestedFamANDAssem.  We used to return these, and later do a check
+       that would report a meaningful error, but the problem is that we
+       would not get the real match, if there was a name override.
+
+2003-07-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * namespace.cs (Namespace, Name): Do not compute the namespace
+       name dynamically, compute it in the constructor.  This reduced
+       memory usage by 1697 KB.
+
+       * driver.cs: Use --pause to pause at the end.
+
+2003-07-17  Peter Williams  <peter@newton.cx>
+
+       * Makefile: Change the name of the test target so that it doesn't
+       conflict with the recursive test target.
+
+2003-07-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (LocalVariableReference.Emit, EmitAssign,
+       AddressOf): Do not use EmitThis, that was wrong, use the actual
+       this pointer.
+
+2003-07-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (MethodData.Define): While checking if a method is an
+       interface implementation, improve the test: If we are not public
+       (use new test here: use the computed MethodAttributes directly,
+       instead of the parsed modifier flags) check if the `implementing'
+       method comes from an interface or not.
+
+       * pending.cs (VerifyPendingMethods): Slightly better error
+       message.
+
+       * makefile: add test target that does the mcs bootstrap.
+
+2003-07-16  Ravi Pratap  <ravi@ximian.com>
+
+       * interface.cs (Define): Do nothing here since there are no
+       members to populate etc. Move the attribute emission out of here
+       since this was just totally the wrong place to put it. Attribute
+       application happens during the 'Emit' phase, not in the 'Define'
+       phase.
+
+       (Emit): Add this method and move the attribute emission here
+
+       * rootcontext.cs (EmitCode): Call the Emit method on interface
+       types too.
+
+2003-07-14  Ravi Pratap M  <ravi@ximian.com>
+
+       * expression.cs (OverloadResolve): Report error only if Location
+       is not 'Null' which means that there was a probe going on.
+
+2003-07-14  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (ConditionalLogicalOperator): New public class to
+       implement user defined conditional logical operators.
+       This is section 14.11.2 in the spec and bug #40505.
+
+2003-07-14  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (FieldExpr.DoResolveLValue): Fixed bug #46198.
+
+2003-07-14  Martin Baulig  <martin@ximian.com>
+
+       * codegen.cs (EmitContext.InFixedInitializer): New public field.
+
+       * ecore.cs (IVariable.VerifyFixed): New interface method.
+
+       * expression.cs (Unary.ResolveOperator): When resolving the `&'
+       operator, check whether the variable is actually fixed.  Fixes bug
+       #36055.  Set a variable definitely assigned when taking its
+       address as required by the spec.
+
+       * statement.cs (LocalInfo.IsFixed): New field.
+       (LocalInfo.MakePinned): Set `IsFixed' to true.
+
+2003-07-14  Ravi Pratap M  <ravi@ximian.com>
+
+       * attribute.cs (Attribute.Resolve): While doing a Member lookup
+       for .ctors, ensure that we only ask for members declared in the
+       attribute type (BindingFlags.DeclaredOnly).
+
+       Fixes bug #43632.
+
+       * expression.cs (Error_WrongNumArguments): Report error 1501
+       correctly the way CSC does.
+
+2003-07-13  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (MemberAccess.ResolveAsTypeStep): Try to do a type
+       lookup on the fully qualified name, to make things like "X.X" work
+       where "X.X" is a fully qualified type name, but we also have a
+       namespace "X" in the using list.  Fixes #41975.
+
+2003-07-13  Martin Baulig  <martin@ximian.com>
+
+       * assign.cs (Assign.GetEmbeddedAssign): New protected virtual
+       function. If we're a CompoundAssign, we need to create an embedded
+       CompoundAssign, not an embedded Assign.
+       (Assign.DoResolve): Make this work for embedded CompoundAssign's.
+       Fixes #45854.
+
+2003-07-13  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (TypeManager.IsNestedChildOf): Make this actually
+       work to fix bug #46088.
+
+2003-07-13  Ravi Pratap <ravi@ximian.com>
+
+       * class.cs (Operator.Emit): Do not emit attributes here - it is
+       taken care of by the Method class that we delegate too. This takes
+       care of bug #45876.
+
+2003-07-10  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (TypeOfVoid): New class.
+       (TypeOf): Report a CS0673 if it's System.Void.  Fixes #42264.
+
+2003-07-10  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodCore.DoDefineParameters): Added CS0225 check;
+       bug #35957.
+
+2003-07-10  Martin Baulig  <martin@ximian.com>
+
+       * rootcontext.cs (RootContext.NamespaceLookup): Take a DeclSpace,
+       not a NamespaceEntry, so we can use DeclSpace.CheckAccessLevel().
+
+       * decl.cs (DeclSpace.FindType): Use DeclSpace.CheckAccessLevel().
+
+       * typemanager.cs (TypeManager.IsAccessibleFrom): Removed.
+
+2003-07-10  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (ArrayCreation): Don't use a byte blob for arrays
+       of decimal.  Fixes #42850.
+
+       NOTE: I also fixed the created byte blob, but this doesn't work on
+       the MS runtime and csc never produces any byte blobs for decimal
+       arrays.
+
+2003-07-10  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (StructInfo.GetStructInfo): Catch deep cycles in
+       structs; fixes #32068.
+       (Block.AddChildVariableNames): Fixed #44302.
+
+2003-07-07  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * namespace.cs: fixed compilation with csc. It's bugzilla #44302.
+
+2003-07-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs: And this test is onger needed.
+
+2003-07-08  Martin Baulig  <martin@ximian.com>
+
+       * rootcontext.cs (RootContext.NamespaceLookup): Ignore
+       inaccessible types.  Fixes #36313.
+
+       * decl.cs (DeclSpace.FindType): Ignore inaccessible types.
+
+       * namespace.cs (NamespaceEntry): Create implicit entries for all
+       namespaces; ie. if we have `namespace N1.N2.N3 { ... }', we create
+       implicit entries for N1.N2 and N1.
+
+2003-07-08  Martin Baulig  <martin@ximian.com>
+
+       Rewrote the handling of namespaces to fix a lot of the issues
+       wrt. `using' aliases etc.
+
+       * namespace.cs (Namespace): Splitted this class into a
+       per-assembly `Namespace' and a per-file `NamespaceEntry'.
+
+       * typemanager.cs (TypeManager.IsNamespace): Removed.
+       (TypeManager.ComputeNamespaces): Only compute namespaces from
+       loaded assemblies here, not the namespaces from the assembly we're
+       currently compiling.
+
+2003-07-08  Martin Baulig  <martin@ximian.com>
+
+       * rootcontext.cs, class.cs: Fixed the CS1530 reporting.
+
+2003-07-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs: Reverted patch from Gonzalo, my previous patch
+       already fixed it.  
+
+       I thought about the memory savings here, but LookupTypeReflection
+       is used under already very constrained scenarios.  Compiling
+       corlib or mcs only exposes one hit, so it would not really reduce
+       any memory consumption.
+
+2003-07-07  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * typemanager.cs: fixes bug #45889 by only adding public types from
+       other assemblies to the list of known types.
+
+2003-07-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs (Attribute.Resolve): Add call to CheckAccessLevel
+       on the type we resolved.
+
+2003-07-05  Martin Baulig  <martin@ximian.com>
+
+       * pending.cs (PendingImplementation.ParentImplements): Don't
+       create the proxy if the parent is abstract.
+
+       * class.cs (TypeContainer.DefineIndexers): Process explicit
+       interface implementations first.  Fixes #37714.
+
+2003-07-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (MemberAccess.ResolveMemberAccess): Events are
+       defined recursively;  but since we modify the input parameters
+       (left is set to `this' temporarily), we reset this value if the
+       left_is_explicit is false, which gives the original semantics to
+       the code.  
+
+       * literal.cs (NullPointer): new class used to represent a null
+       literal in a pointer context.
+
+       * convert.cs (Convert.ImplicitReferenceConversion): Is the target
+       type is a pointer, use a NullPointer object instead of a
+       NullLiteral.   Closes 43687
+
+       (ExplicitConversion): Convert pointer values using
+       the conv opcode to the proper type.
+
+       * ecore.cs (New): change ValueTypeVariable property into a method,
+       that returns whether the valuetype is suitable for being used.
+
+       * expression.cs (Binary.DoNumericPromotions): Only return if we
+       the int constant was a valid uint, and we can return both left and
+       right as uints.  If not, we continue processing, to trigger the
+       type conversion.  This fixes 39018.
+
+       * statement.cs (Block.EmitMeta): During constant resolution, set
+       the CurrentBlock property on the emitcontext, so that we resolve
+       constants propertly.
+
+2003-07-02  Martin Baulig  <martin@ximian.com>
+
+       * codegen.cs (EmitContext.NeedExplicitReturn): New public variable.
+       (EmitContext.EmitTopBlock): Emit an explicit return if it's set.
+
+       * statement.cs (Try.Resolve): Set ec.NeedExplicitReturn rather
+       than emitting it here.
+
+       * statement.cs: Fixed some more flow analysis bugs.
+
+2003-07-02  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodData.Define): When implementing interface
+       methods, set Final unless we're Virtual.
+
+       * decl.cs (MemberCore.CheckMethodAgainstBase): Make the CS0506
+       check work for interface methods.
+
+2003-07-01  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (EmitContext.This): Replaced this property with a
+       GetThis() method which takes a Location argument.  This ensures
+       that we get the correct error location for a CS0188.
+
+2003-07-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs: (Convert.ConvertIntLiteral): Add test for
+       ImplicitStandardConversion.
+
+       * class.cs (TypeContainer.GetClassBases): Small bug fix for 45649.
+
+2003-07-01  Zoltan Varga  <vargaz@freemail.hu>
+
+       * expression.cs (ResolveOperator): Fix Concat (string, string, string)
+       optimization.
+
+2003-06-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Constructor.Define): Turn off initlocals for unsafe
+       constructors.
+
+       (MethodData.Define): Turn off initlocals for unsafe methods.
+
+2003-06-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * decl.cs (DeclSpace.CheckAccessLevel): Make this routine
+       complete;  Fixes #37521.
+
+       * delegate.cs: Use Modifiers.TypeAttr to compute the
+       TypeAttributes, instead of rolling our own.  This makes the flags
+       correct for the delegates.
+
+2003-06-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Constructor.Define): Set the private flag for static
+       constructors as well.
+
+       * cs-parser.jay (statement_expression): Set the return value to
+       null, to avoid a crash when we catch an error.
+
+2003-06-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Applied patch from Jackson that adds support for
+       extern and unsafe modifiers to destructor declarations.
+
+       * expression.cs: Report error 21 if the user is trying to index a
+       System.Array.
+
+       * driver.cs: Add an error message, suggested by the bug report.
+
+       * class.cs (TypeContainer.Emit): Only call EmitFieldInitializers
+       if we do not have a ": this ()" constructor initializer.  Fixes 45149
+
+2003-06-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * namespace.cs: Add some information to reduce FAQs.
+
+2003-06-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * cfold.cs (BinaryFold): BitwiseAnd, BitwiseOr: handle other
+       underlying enumeration types.  Fixes #43915.
+
+       * expression.cs: Treat ushort/short as legal values to be used in
+       bitwise operations.
+
+Wed Jun 4 13:19:04 CEST 2003 Paolo Molaro <lupus@ximian.com>
+
+       * delegate.cs: transfer custom attributes for paramenters from
+       the delegate declaration to Invoke and BeginInvoke.
+
+Tue Jun 3 11:11:08 CEST 2003 Paolo Molaro <lupus@ximian.com>
+
+       * attribute.cs: handle custom marshalers and emit marshal info
+       for fields, too.
+
+2003-05-28  Hector E. Gomez Morales  <hgomez_36@flashmail.com>
+
+       * makefile.gnu: Added anonymous.cs to the compiler sources.
+
+2003-05-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * iterators.cs: Change the name of the proxy class to include two
+       underscores.
+
+       * cs-parser.jay: Update grammar to include anonymous methods.
+
+       * anonymous.cs: new file.
+
+2003-05-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Field.Define): Add missing test for pointers and
+       safety. 
+
+2003-05-27  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ArrayAccess.GetStoreOpCode): For System.IntPtr,
+       we use the stobj opcode.
+
+       (ArrayCreation.EmitDynamicInitializers): Revert Miguel's patch
+       since it wasn't the correct fix. 
+
+       It still is puzzling that we are required to use stobj for IntPtr
+       which seems to be a ValueType.
+
+2003-05-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Consider using aliases
+       during regular simple name resolution.   Now, the trick is that
+       instead of returning for processing the simplename, we do a
+       TypeManager.LookupType (ie, a rooted lookup as opposed to a
+       contextual lookup type).   If a match is found, return that, if
+       not, return for further composition.
+
+       This fixes long-standing 30485.
+
+       * expression.cs (ArrayCreation.EmitDynamicInitializers): When
+       using the address to initialize an object, do an Stobj instead of
+       using the regular Stelem.
+
+       (IndexerAccess.Emit, IndexerAccess.EmitAssign):
+       Pass `is_base_indexer' to Invocation.EmitCall instead of false.
+       Because if we are a BaseIndexerAccess that value will be true.
+       Fixes 43643.
+
+       * statement.cs (GotoCase.Resolve): Return after reporting an
+       error, do not attempt to continue. 
+
+       * expression.cs (PointerArithmetic.Emit): If our operand is a
+       long, convert our constants to match the operand before
+       multiplying.  Convert to I type before adding.   Fixes 43670.
+
+2003-05-14  Ravi Pratap  <ravi@ximian.com>
+
+       * enum.cs (ImplicitConversionExists) : Rename to
+       ImplicitEnumConversionExists to remove ambiguity. 
+
+       * ecore.cs (NullCast): New type of cast expression class which
+       basically is very similar to EmptyCast with the difference being
+       it still is a constant since it is used only to cast a null to
+       something else
+       (eg. (string) null)
+
+       * convert.cs (ImplicitReferenceConversion): When casting a null
+       literal, we return a NullCast.
+
+       * literal.cs (NullLiteralTyped): Remove - I don't see why this
+       should be around anymore.
+
+       The renaming (reported was slightly wrong). Corrections:
+
+       ConvertImplicitStandard -> ImplicitConversionStandard
+       ConvertExplicitStandard -> ExplicitConversionStandard
+
+       * expression.cs (StaticCallExpr.MakeSimpleCall): Resolve arguments
+       before passing them in !
+
+       * convert.cs (ImplicitConversionStandard): When comparing for
+       equal expr and target types, ensure that expr is not a
+       NullLiteral.
+
+       In general, we must not be checking (expr_type ==
+       target_type) in the top level conversion methods
+       (ImplicitConversion, ExplicitConversion etc). This checking is
+       done in the methods that they delegate to.
+
+2003-05-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * convert.cs: Move Error_CannotConvertType,
+       ImplicitReferenceConversion, ImplicitReferenceConversionExists,
+       ImplicitNumericConversion, ImplicitConversionExists,
+       ImplicitUserConversionExists, StandardConversionExists,
+       FindMostEncompassedType, FindMostSpecificSource,
+       FindMostSpecificTarget, ImplicitUserConversion,
+       ExplicitUserConversion, GetConversionOperators,
+       UserDefinedConversion, ConvertImplicit, ConvertImplicitStandard,
+       TryImplicitIntConversion, Error_CannotConvertImplicit,
+       ConvertImplicitRequired, ConvertNumericExplicit,
+       ExplicitReferenceConversionExists, ConvertReferenceExplicit,
+       ConvertExplicit, ConvertExplicitStandard from the ecore.cs into
+       its own file.
+
+       Perform the following renames:
+
+       StandardConversionExists -> ImplicitStandardConversionExists
+       ConvertImplicit -> ImplicitConversion
+       ConvertImplicitStandard -> ImplicitStandardConversion
+       TryImplicitIntConversion -> ImplicitIntConversion
+       ConvertImplicitRequired -> ImplicitConversionRequired
+       ConvertNumericExplicit -> ExplicitNumericConversion
+       ConvertReferenceExplicit -> ExplicitReferenceConversion
+       ConvertExplicit -> ExplicitConversion
+       ConvertExplicitStandard -> ExplicitStandardConversion
+
+2003-05-19  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (TypeInfo.StructInfo): Made this type protected.
+       (TypeInfo): Added support for structs having structs as fields.
+
+       * ecore.cs (FieldExpr): Implement IVariable.
+       (FieldExpr.DoResolve): Call VariableInfo.GetSubStruct() to get the
+       VariableInfo for the field.
+
+2003-05-18  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (This.DoResolve): Report a CS0027 if we're
+       emitting a field initializer.
+
+2003-05-18  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (This.ResolveBase): New public function.
+       (This.DoResolve): Check for CS0188.
+
+       * codegen.cs (EmitContext.This): Just call This.ResolveBase(), not
+       This.Resolve().
+
+       * ecore.cs (MethodGroupExpr.DoResolve): Set the
+       `instance_expression' to null if we don't have any non-static
+       methods.
+
+2003-05-18  Martin Baulig  <martin@ximian.com>
+
+       Reworked the way how local variables and parameters are handled by
+       the flow analysis code.
+
+       * statement.cs (TypeInfo, VariableMap): New public classes.
+       (VariableInfo): New public class.  This is now responsible for
+       checking whether a variable has been assigned.  It is used for
+       parameters and local variables.
+       (Block.EmitMeta): Take the InternalParameters as argument; compute
+       the layout of the flow vectors here.
+       (Block.LocalMap, Block.ParameterMap): New public properties.
+       (FlowBranching): The .ctor doesn't get the InternalParameters
+       anymore since Block.EmitMeta() now computes the layout of the flow
+       vector.
+       (MyStructInfo): This class is now known as `StructInfo' and nested
+       in `TypeInfo'; we don't access this directly anymore.
+
+       * ecore.cs (IVariable): Added `VariableInfo VariableInfo'
+       property and removed IsAssigned(), IsFieldAssigned(),
+       SetAssigned() and SetFieldAssigned(); we now call them on the
+       VariableInfo so we don't need to duplicate this code everywhere.
+
+       * expression.cs (ParameterReference): Added `Block block' argument
+       to the .ctor.
+       (LocalVariableReference, ParameterReference, This): The new
+       VariableInfo class is now responsible for all the definite
+       assignment stuff.
+
+       * codegen.cs (EmitContext.IsVariableAssigned, SetVariableAssigned,
+       IsParameterAssigned, SetParameterAssigned): Removed.
+
+2003-05-18  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (InitCoreTypes): Try calling
+       SetCorlibTypeBuilders() with 4 args; if that fails, fall back to
+       the 3-args-version.  Corlib now also needs our `void_type'.
+       (GetMethod): Added overloaded version which takes an optional
+       `bool report_errors' to allow lookups of optional methods.
+
+2003-05-12  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (VariableInfo): Renamed to LocalInfo since it's
+       only used for locals and not for parameters.
+
+2003-05-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * support.cs (InternalParameters.ParameterType): Return the
+       ExternalType of the parameter.
+
+       * parameter.cs (Parameter.ExternalType): drop the two arguments,
+       they were unused.
+
+2003-05-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (MethodData.Define): Do not set the `newslot' on
+       interface members, if they are also flagged as "override".
+
+       * expression.cs (UnaryMutator.EmitCode): Simple workaround to emit
+       better code for ++i and i++.  This only works for static fields
+       and local variables.
+
+       * typemanager.cs (LookupDeclSpace): Add new method, sometimes we
+       want to pull the DeclSpace out of the builder_to_declspace instead
+       of the TypeBuilder (like in TypeContainer.FindMembers).
+
+       * class.cs (TypeContainer.FindMembers): Use LookupDeclSpace
+       instead of LookupTypeContainer.  Fixes the crash on .NET for
+       looking up interface members.
+
+       * const.cs: Create our own emit context during the Definition
+       stage, so that constants are evaluated in the proper context, when
+       a recursive definition happens.
+
+2003-05-11  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Block.CreateSwitchBlock): New method.  Creates a
+       new block for a switch section.
+       (Block.AddLabel, Block.LookupLabel): If we're a switch section, do
+       the adding/lookup in the switch block.  Fixes #39828.
+
+2003-05-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (UnaryMutator.LoadOneAndEmitOp): Missing
+       functionality: I needed to convert the data after I had performed
+       the add/sub operation into the operands type size.
+
+       * ecore.cs (ImplicitReferenceConversion): When boxing an interface
+       pass the type for the box operation, otherwise the resulting
+       object would have been of type object.
+
+       (BoxedCast): Add constructor to specify the type to box as.
+
+2003-05-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * iterators.cs: I was reusing the `count' variable inadvertently,
+       take steps to not allow this to happen.
+
+2003-05-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs (Attribute.Resolve): Params attributes are encoded
+       by creating an array at the point where the params starts and
+       putting all those arguments there, then adjusting the size of the
+       array.
+
+2003-05-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (New.AddressOf): Implement interface
+       IMemoryLocation.  This is used when the `new' operator is used in
+       the context of an invocation to a method on a value type.
+
+       See http://bugzilla.ximian.com/show_bug.cgi?id=#42390 for an
+       example. 
+
+       * namespace.cs: Also check the using aliases here.
+
+       * driver.cs: Move the test for using validity after the types have
+       been entered, so we do a single pass that also includes the using
+       aliases. 
+
+       * statement.cs (Try.Resolve): Avoid crashing if there is a failure
+       in the regular case.   CreateSiblingForFinally is doing extra
+       error checking.
+
+       * attribute.cs (GetAttributeArgumentExpression): Store the result
+       on an out value, and use the return value to indicate failure
+       instead of using null (which is a valid return for Constant.GetValue).
+
+       * statement.cs: Perform the analysis flow for the increment
+       portion after the statement, because this will be the real flow of
+       execution.  Fixes #42385
+
+       * codegen.cs (EmitContext.EmitArgument,
+       EmitContext.EmitStoreArgument): New helper functions when the
+       RemapToProxy flag is set.
+
+       * expression.cs (ParameterReference.EmitLdarg): Expose this useful
+       function.
+
+       Add support for remapping parameters. 
+
+       * iterators.cs: Propagate parameter values;  Store parameter
+       values in the proxy classes.
+
+2003-05-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (FieldExpr): Fix an obvious bug.  static fields do not
+       need a proxy reference;  I do not know what I was thinking
+
+       * cs-parser.jay (constructor_initializer): catch another error,
+       and display nice message.
+
+       (field_declaration): catch void field declaration
+       to flag a better error. 
+
+       * class.cs (MemberBase.CheckBase): Report an error instead of a
+       warning if a new protected member is declared in a struct. 
+       (Field.Define): catch the error of readonly/volatile.
+
+       * ecore.cs (FieldExpr.EmitAssign): reuse the field lookup.
+
+       (FieldExpr.AddressOf): ditto.  Catch error where the address of a
+       volatile variable is taken
+
+2003-05-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Fixed.Resolve): Report an error if we are not in
+       an unsafe context.
+
+2003-05-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs: reuse the code that handles type clashes for
+       delegates and enumerations.
+
+       * class.cs (Report28): Always report.
+
+       * expression.cs (EncodeAsAttribute): Allow nulls here.
+
+2003-04-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs (Attribute.GetAttributeArgumentExpression): Moved
+       the functionality for testing whether an expression is valid for
+       an attribute here.  Also handle the case of arrays of elements
+       being stored. 
+
+       * expression.cs (ArrayCreation.EncodeAsAttribute): Add support for
+       encoding a linear array into an array of objects that are suitable
+       to be passed to an CustomAttributeBuilder.
+
+       * delegate.cs: Check unsafe types being used outside of an Unsafe context.
+
+       * ecore.cs: (FieldExpr): Handle field remapping here.
+
+       * iteratators.cs: Pass the instance variable (if the method is an
+       instance method) to the constructors, so we can access the field
+       variables on the class.
+
+       TODO: Test this with structs.  I think the THIS variable on
+       structs might have to be a pointer, and not a refenrece
+
+2003-04-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs (EmitContext.Mapvariable): Adds a mechanism to map
+       local variables to fields in a proxy class.
+
+       * iterators.cs (PopulateProxy): Rename our internal fields to
+       <XXX>.  
+       Create a <THIS> field if we are an instance method, so we can
+       reference our parent container variables.
+       (MapVariable): Called back from the EmitContext code to enter a
+       new variable to field mapping into the proxy class (we just create
+       a FieldBuilder).
+
+       * expression.cs
+       (LocalVariableReference.{Emit,EmitAssign,AddressOf}): Add support
+       for using the remapped locals to fields.
+
+       I placed the code here, because that gives the same semantics to
+       local variables, and only changes the Emit code.
+
+       * statement.cs (Fixed.Resolve): it is not allowed to have fixed
+       statements inside iterators.
+       (VariableInfo): Add a FieldBuilder for the cases when we are
+       remapping local variables to fields in a proxy class
+
+       * ecore.cs (SimpleNameResolve): Avoid testing two times for
+       current_block != null.
+
+       * statement.cs (Swithc.SimpleSwitchEmit): Removed code that did
+       not cope with strings, as it has been moved to the
+       TableSwitchEmit.  Fixed bug in switch generation.
+
+       * expression.cs (New.DoResolve): Provide more context for the user
+       when reporting an error.
+
+       * ecore.cs (Expression.LoadFromPtr): Use ldind_i when loading
+       pointers. 
+
+       * expression.cs (MemberAccess.DoResolve): When we get a type back,
+       check the permissions for it.  Note than in a type-resolution
+       context the check was already present in DeclSpace.ResolveType,
+       but was missing from the MemberAccess.
+
+       (ArrayCreation.CheckIndices): warn if the user has
+       more nested levels of expressions, but there are no more
+       dimensions specified.  Avoids crash on bug 41906.
+
+2003-04-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Block): replace Implicit bool, for a generic
+       flags.   
+       New flag: `Unchecked'.  This is used during the EmitMeta phase
+       (which is out-of-line with the regular Resolve/Emit process for a
+       statement, as this is done ahead of time, but still gets a chance
+       to call constant resolve).
+
+       (Block.Flags): new enum for adding a new flag.
+
+       (Block.EmitMeta): track the state of unchecked.
+
+       (Unchecked): Set the "UnChecked" flags on any blocks we enclose,
+       to enable constant resolution to work there as well.
+
+2003-04-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (ienumerable_type): Also look up
+       System.Collections.IEnumerable. 
+
+2003-04-21  Miguel de Icaza  <miguel@ximian.com>
+
+       TODO: Test more than one conditional per method.
+
+       * class.cs (Indexer.Define): Report the location where the user is
+       referencing the unsupported feature.
+
+       (MethodData): Overload the use of `conditionals' to
+       minimize the creation of needless ArrayLists.   This saves roughly
+       212kb on my machine.
+
+       (Method): Implement the new IIteratorContainer interface.
+       (Method.SetYields): Implement the method by setting the ModFlags
+       to contain METHOD_YIELDS.
+
+       * expression.cs (Unary.ResolveOperator): Use expr_type, not Expr,
+       which just got set to null.
+
+       * iterators.cs: New file.
+
+       (Yield, YieldBreak): New statements.
+
+       * statement.cs (Return.Resolve): Flag an error if we are used in
+       an iterator method.
+
+       * codegen.cs (InIterator): New flag set if the code is being
+       compiled in an iterator method.
+
+       * modifiers.cs: New flag METHOD_YIELDS.  This modifier is an
+       internal modifier, and we just use it to avoid adding extra
+       fields, as this is seldom used.  
+
+       * cs-parser.jay: Add yield_statement (yield and yield break).
+
+       * driver.cs: New flag -v2 to turn on version 2 features. 
+
+       * cs-tokenizer.cs (Tokenizer): Add yield and __yield to the
+       hashtable when v2 is enabled.
+
+2003-04-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (TypeManager.NamespaceClash): Use to check if
+       there is already a namespace defined with this name.
+
+       (TypeManager.InitCoreTypes): Remove the temporary workaround, as
+       people upgraded their corlibs.
+
+       (TypeManager.CoreLookupType): Use LookupTypeDirect, as we
+       always use fully qualified types, no need to use the compiler
+       front end.
+
+       (TypeManager.IsNamespace): Use binarysearch.
+
+       * class.cs (AddClass, AddStruct, AddInterface, AddEvent,
+       AddDelegate): I did not quite use the new IsValid API properly: I
+       have to pass the short-name and the fullname.  I was passing only
+       the basename instead of the fullname sometimes. 
+
+       (TypeContainer.DefineType): call NamespaceClash.
+
+       * interface.cs (Interface.DefineType): use NamespaceClash before
+       defining the type.
+
+       * delegate.cs (Delegate.DefineType): use NamespaceClash before
+       defining the type.
+
+       * enum.cs: (Enum.DefineType): use NamespaceClash before
+       defining the type.
+
+       * typemanager.cs (: 3-line patch that gives us some tasty 11%
+       speed increase.  First, use the negative_hits cache when we get a
+       negative.  Second, add the type with its full original name
+       instead of the new . and + encoded name (reflection uses + to
+       separate type from a nested type).  Use LookupTypeReflection
+       directly which bypasses the type->name hashtable (that we already
+       know does not contain the type.
+
+       * decl.cs (DeclSpace.ResolveTypeExpr): track the
+       location/container type. 
+
+       * driver.cs: When passing utf8, use directly the UTF8Encoding.
+
+2003-04-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * decl.cs (ResolveTypeExpr): Mirror check acess here too.
+
+       * delegate.cs (NewDelegate.Resolve): Test whether an instance
+       method is being referenced in the method group from a static
+       context, and report error 120 if so.
+
+       * expression.cs, ecore.cs (Error_UnexpectedKind): New name for
+       Error118. 
+
+       * typemanager.cs: Add intermediate namespaces (if a namespace A.B
+       is created, we create the A namespace).
+
+       * cs-parser.jay: A namespace also introduces a DeclarationFound.
+       Fixes #41591
+
+2003-04-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (GetReferenceType, GetPointerType): In .NET each
+       invocation to ModuleBuilder.GetType with the same values will
+       return a new type instance, so we need to cache its return
+       values. 
+
+       * expression.cs (Binary.ResolveOperator): Only allow the compare
+       operators on enums if they are of the same type.
+
+       * ecore.cs (Expression.ImplicitReferenceConversion): handle target
+       types of ValueType on their own case.  Before we were giving them
+       the same treatment as objects.
+
+       * decl.cs (DeclSpace.IsValid): IsValid takes the short name and
+       fullname.  Short name is used to compare against container name.
+       Fullname is used to check against defined namespace names.
+
+       * class.cs (AddProperty, AddField, AddClass, AddStruct, AddEnum,
+       AddDelegate, AddEvent): Pass new parameter to DeclSpace.IsValid
+
+       (Method.CheckBase): Call parent.
+       (MemberBase.CheckBase): Check for protected members on sealed
+       classes.
+       (PropertyBase.CheckBase): Call parent.
+       (Field.Define): Call parent.
+
+       * report.cs: Negative error codes are now mapped to 8000 - code,
+       so that the display is render more nicely.
+
+       * typemanager.cs: Do not use try/catch, instead report a regular
+       error. 
+
+       (GetPointerType, GetReferenceType): These methods provide
+       mechanisms to obtain the T* and T& from a T.  We had the code
+       previously scattered around the code base, and it also used
+       TypeManager.LookupType that would go through plenty of caches.
+       This one goes directly to the type source.
+
+       In some places we did the Type.GetType followed by
+       ModuleBuilder.GetType, but not in others, so this unifies the
+       processing as well.
+
+       * namespace.cs (VerifyUsing): Perform a non-lazy approach to using
+       statements now that we have namespace information.
+
+       * typemanager.cs (IsNamespace): New method, returns whether the
+       string presented is a namespace or not.
+
+       (ComputeNamespaces): New public entry point, computes the list of
+       available namespaces, using the GetNamespaces API call in Mono, or
+       the slower version in MS.NET.   
+
+       Now before we start the semantic analysis phase, we have a
+       complete list of namespaces including everything that the user has
+       provided.
+
+       Deleted old code to cache namespaces in .nsc files.
+
+2003-04-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs: (TypeContainer.DefineDefaultConstructor): Use the
+       class/struct location definition Location for the implicit
+       constructor location.
+
+       (Operator.Define): Use the location of the operator for the
+       implicit Method definition.
+
+       (Constructor.Emit): use the constructor location for the implicit
+       base initializer constructor.
+
+       * ecore.cs: Remove ITypeExpression.  This interface is now gone,
+       and the Expression class now contains two new methods:
+
+       ResolveAsTypeStep and ResolveAsTypeTerminal.  This is used to
+       isolate type lookup from the rest of the resolution process.
+
+       Since we use Expressions to hold type definitions due to the way
+       we parse the input we have historically overloaded Resolve to
+       perform the Type lookups if a special flag is passed.  Now this is
+       eliminated and two methods take their place. 
+
+       The differences in the two methods between xStep and xTerminal is
+       that xStep is involved in our current lookup system that uses
+       SimpleNames to compose a name, while xTerminal is used just to
+       catch the case where the simplename lookup failed.
+
+2003-04-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ResolveMemberAccess): Remove redundant code.
+       TypeExpr expressions are always born fully resolved.
+
+       * interface.cs (PopulateMethod): Do not lookup the types twice.
+       We were doing it once during SemanticAnalysis and once during
+       PopulateMethod.
+
+       * cs-parser.jay: Due to our hack in the grammar, things like A.B[]
+       in local variable type definitions, were being returned as a
+       SimpleName (we decomposed everything into a string), that is
+       because primary_expression was being used instead of a type in the
+       grammar (reduce/reduce conflicts).
+
+       The part that was wrong is that we converted the expression into a
+       string (an oversimplification in one hand, compounded with primary
+       expressions doing string concatenation).
+
+       So things like:
+
+       A.B.C [] x;
+
+       Would return "A.B.C[]" as a SimpleName.  This stopped things like
+       using clauses from working on this particular context.  And a type
+       was being matched directly against "A.B.C[]".
+
+       We now use the correct approach, and allow for ComposedCast to be
+       part of the unary expression.  So the "A.B.C []" become a composed
+       cast of "A.B.C" (as a nested group of MemberAccess with a
+       SimpleName at the end) plus the rank composition "[]". 
+
+       Also fixes 35567
+
+2003-04-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * decl.cs (CheckAccessLevel): Implement the NestedPrivate rules
+       for the access level checking.
+
+       * class.cs: Cosmetic changes.  Renamed `TypeContainer parent' to
+       `TypeContainer container', because I kept getting confused when I
+       was debugging this code.
+
+       * expression.cs (Indexers): Instead of tracking getters/setters,
+       we now track them in parallel.  We create one arraylist less, but
+       most importantly it is possible now for the LValue code to find a
+       matching get for a set.
+
+       (IndexerAccess.DoResolveLValue): Update the code.
+       GetIndexersForType has been modified already to extract all the
+       indexers from a type.  The code assumed it did not.
+
+       Also make the code set the correct return type for the indexer.
+       This was fixed a long time ago for properties, but was missing for
+       indexers.  It used to be void_type.
+
+       (Binary.Emit): Test first for doubles instead of
+       floats, as they are more common.
+
+       (Binary.EmitBranchable): Use the .un version of the branch opcodes
+       when dealing with floats and the <=, >= operators.  This fixes bug
+       #39314 
+
+       * statement.cs (Foreach.EmitArrayForeach): bug fix: The code used
+       to load the array value by emitting a load on the foreach variable
+       type.  This was incorrect.  
+
+       We now emit the code to load an element using the the array
+       variable type, and then we emit the conversion operator.
+
+       Fixed #40176
+
+2003-04-10  Zoltan Varga  <vargaz@freemail.hu>
+
+       * attribute.cs: Avoid allocation of ArrayLists in the common case.
+
+2003-04-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (MethodSignature.InheritableMemberSignatureCompare):
+       test for protection before we test for signatures. 
+
+       (MethodSignature.ToString): implement.
+
+       * expression.cs (Unary.TryReduceNegative): Add missing minus sign
+       to the case where we reduced into a LongConstant.
+
+       * decl.cs (CheckAccessLevel): If the type is an array, we can not
+       depend on whether the information is acurrate, because the
+       Microsoft runtime will always claim that the array type is public,
+       regardless of the real state.
+
+       If the type is a pointer, another problem happens: the type is
+       reported as non-public in Microsoft.  
+
+       In both cases we have to call CheckAccessLevel recursively with
+       the underlying type as the argument to be tested.
+
+2003-04-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs (Assign.Emit): If we are dealing with a compound
+       assignment expression, we should use the code path that stores the
+       intermediate result in a temporary value.  This fixes #40903.
+
+       *expression.cs (Indirection.ToString): Provide ToString method for
+       debugging. 
+
+2003-04-08  Zoltan Varga  <vargaz@freemail.hu>
+
+       * class.cs: Null out fields holding references to Block objects so
+       they can be garbage collected.
+
+       * expression.cs (OverloadResolve): Remove unused local.
+
+2003-04-07  Martin Baulig  <martin@ximian.com>
+
+       * codegen.cs (EmitContext.CurrentFile): New public field.
+       (EmitContext.Mark): Use the CurrentFile to check whether the
+       location is in the correct file.
+       (EmitContext.EmitTopBlock): Initialize CurrentFile here.
+
+2003-04-07  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (Expression.ResolveBoolean): Don't call ec.Mark().
+
+       * codegen.cs (EmitContext.EmitTopBlock): Don't call Mark() on the
+       location.  [FIXME: The location argument which gets passed to this
+       method is sometimes wrong!]
+
+2003-04-07  Nick Drochak <ndrochak@gol.com>
+
+       * codegen.cs: Be more verbose when we can't find the symbol writer dll.
+
+2003-04-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Indirection.EmitAssign): We were using the
+       temporary, but returning immediately instead of continuing the
+       EmitAssing flow.
+
+2003-04-06  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Don't report an error
+       if it's a nested child, but also deriving from the outer class.
+       See test 190.cs.
+
+       * typemanager.cs (IsNestedChildOf): Make this work if it's a
+       nested child, but also deriving from the outer class.  See
+       test-190.cs.
+       (FilterWithClosure): We may access private members of the outer
+       class if we're a nested child and deriving from the outer class.
+       (RealMemberLookup): Only set `closure_private_ok' if the
+       `original_bf' contained BindingFlags.NonPublic.
+
+2003-04-05  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (SizeOf.DoResolve): Use ResolveTypeExpr, so we can
+       probe if its a type parameter, and if so, flag an error.
+
+       * decl.cs: Move here the SetParameterInfo code from class.cs.
+       Handle IsGeneric here.
+
+       Handle a variety of errors in the parameter info definition.
+
+       * ecore.cs (SimpleName.DoResolveType): Handle look ups for generic
+       type parameters here.
+
+       * cs-parser.jay (class_declaration): report errors for parameters
+       here as well.
+
+2003-01-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * generic.cs: New file, contains support code for generics.
+
+       * cs-parser.jay: Remove OP_SHIFT_LEFT, OP_SHIFT_RIGHT,
+       OP_SHIFT_LEFT_ASSIGN, OP_SHIFT_RIGHT_ASSIGN.
+
+       Update parser for the above removals.
+
+       * cs-tokenizer.cs: Do not handle <<= or >>= specially.  This is
+       now taken care of in the parser.
+
+2003-04-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Event.Define): Do not allow abstract events to have
+       initializers. 
+
+2003-04-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Add error productions for ADD/REMOVE missing a
+       block in event declarations.
+
+       * ecore.cs (FieldExpr.AddressOf): If our instance expression is a
+       value type, get its address.
+
+       * expression.cs (Is.Emit): For action `LeaveOnStack' we were
+       leaving a class on the stack instead of a boolean value (int
+       0/1).  Change the code so we compare against null, and then the
+       result against zero.
+
+       * class.cs (TypeContainer.GetClassBases): We were checking for the
+       parent class being sealed too late.
+
+       * expression.cs (Binary.Emit): For <= and >= when dealing with
+       floating point values, use cgt.un and clt.un instead of cgt and
+       clt alone.
+
+2003-04-01  Zoltan Varga  <vargaz@freemail.hu>
+
+       * statement.cs: Apply the same optimization as MS: skip the 
+       GetEnumerator returning an IEnumerator, and use the one returning a 
+       CharEnumerator instead. This allows us to avoid the try-finally block 
+       and the boxing.
+
+2003-03-31  Gaurav Vaish <gvaish_mono@lycos.com>
+
+       * cs-parser.jay: Attributes cannot be applied to
+                        namespaces. Fixes #40473
+
+2003-03-31  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * class.cs:
+       (Add*): check if the name is valid using the full name for constants,
+       fields, properties and events.
+
+2003-03-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * enum.cs (Enum.DefineType, Enum.IsValidEnumConstant): Also allow
+       char constants to be part of the enumeration.
+
+       * expression.cs (Conditional.DoResolve): Add support for operator
+       true. Implements the missing functionality from 14.12
+
+       * class.cs (TypeContainer.CheckPairedOperators): Report error for missmatch on
+       operator true/false as required by the spec.
+
+       * expression.cs (Unary.ResolveOperator): In LogicalNot, do an
+       implicit conversion to boolean.
+
+       * statement.cs (Statement.ResolveBoolean): A boolean expression is
+       also one where the type implements `operator true'. 
+
+       * ecore.cs (Expression.GetOperatorTrue): New helper routine to
+       get an expression that will invoke operator true based on an
+       expression.  
+
+       (GetConversionOperators): Removed the hack that called op_True
+       here.  
+
+       (Expression.ResolveBoolean): Move this from Statement.
+
+2003-03-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (FieldExpr): do not allow initialization of initonly
+       fields on derived classes
+
+2003-03-13  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Block.Emit): Call ig.BeginScope() and
+       ig.EndScope() when compiling with debugging info; call
+       LocalBuilder.SetLocalSymInfo _after_ opening the scope.
+
+2003-03-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Indexers): Do not construct immediately, allow
+       for new members to be appended as we go.  Fixes 38143
+
+2003-03-07  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * expression.cs: save/restore context when resolving an unchecked
+       expression.
+
+2003-03-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * cfold.cs: Catch division by zero in modulus operator during
+       constant folding.
+
+2003-03-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * interface.cs (Interface.DefineMembers): Avoid defining members
+       twice. 
+
+2003-02-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: handle the +/- options for -noconfig
+
+       * statement.cs (Unckeched.Resolve): Also track the state of
+       unchecked in the Resolve phase.
+
+2003-02-27  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (Expression.MemberLookup): Don't create a
+       MethodGroupExpr for something which is not a method.  Fixes #38291.
+
+2003-02-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (MemberBase.CheckParameters): Also check that the type
+       is unmanaged if it is a pointer.
+
+       * expression.cs (SizeOf.Resolve): Add location information.
+
+       * statement.cs (Block.EmitMeta): Flag error (208) if a pointer to
+       a managed type is declared.
+
+       * expression.cs (Invocation.VerifyArgumentsCompat): Check for the
+       parameter modifiers as well.  Fixes bug 38606
+
+       * class.cs: Very sad.  Am backing out the speed up changes
+       introduced by the ArrayList -> Array in the TypeContainer, as they
+       were not actually that much faster, and introduced a bug (no error
+       reports on duplicated methods).
+
+       * assign.cs (CompoundAssign.DoLResolve): Resolve the original
+       source first, this will guarantee that we have a valid expression
+       before calling in lower levels functions that will require a
+       resolved object.  Then use this original_source in the
+       target.ResolveLValue instead of the original source that was
+       passed to us.
+
+       Another change.  Use target.Resolve instead of LValueResolve.
+       Although we are resolving for LValues, we will let the Assign code
+       take care of that (it will be called again from Resolve).  This
+       basically allows code like this:
+
+       class X { X operator + (X x, object o) {} X this [int idx] { get; set; } }
+       class Y { void A (X x) { x [0] += o; }
+
+       The problem was that the indexer was trying to resolve for
+       set_Item (idx, object o) and never finding one.  The real set_Item
+       was set_Item (idx, X).  By delaying the process we get the right
+       semantics. 
+
+       Fixes bug 36505
+
+2003-02-23  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Block.Emit): Override this and set ec.CurrentBlock
+       while calling DoEmit ().
+
+       * codegen.cs (EmitContext.Mark): Don't mark locations in other
+       source files; if you use the #line directive inside a method, the
+       compiler stops emitting line numbers for the debugger until it
+       reaches the end of the method or another #line directive which
+       restores the original file.
+
+2003-02-23  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (FlowBranching.UsageVector.MergeChildren): Fix bug #37708.
+
+2003-02-23  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (Block.AddChildVariableNames): We need to call this
+       recursively, not just for our immediate children.
+
+2003-02-23  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Event.Define): Always make the field private, like csc does.
+
+       * typemanager.cs (TypeManager.RealMemberLookup): Make events
+       actually work, fixes bug #37521.
+
+2003-02-23  Miguel de Icaza  <miguel@ximian.com>
+
+       * delegate.cs: When creating the various temporary "Parameters"
+       classes, make sure that we call the ComputeAndDefineParameterTypes
+       on those new parameters (just like we do with the formal ones), to
+       allow them to be resolved in the context of the DeclSpace.
+
+       This fixes the bug that Dick observed in Bugzilla #38530.
+
+2003-02-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ResolveMemberAccess): When resolving a constant,
+       do not attempt to pull a constant if the value was not able to
+       generate a valid constant.
+
+       * const.cs (LookupConstantValue): Do not report more errors than required.
+
+2003-02-19  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * expression.cs: fixes bug #38328.
+
+2003-02-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs: Changed all the various members that can be part of a
+       class from being an ArrayList to be an Array of the right type.
+       During the DefineType type_list, interface_list, delegate_list and
+       enum_list are turned into types, interfaces, delegates and enums
+       arrays.  
+
+       And during the member population, indexer_list, event_list,
+       constant_list, field_list, instance_constructor_list, method_list,
+       operator_list and property_list are turned into their real arrays.
+
+       Although we could probably perform this operation earlier, for
+       good error reporting we need to keep the lists and remove the
+       lists for longer than required.
+
+       This optimization was triggered by Paolo profiling the compiler
+       speed on the output of `gen-sample-program.pl' perl script. 
+
+       * decl.cs (DeclSpace.ResolveType): Set the ContainerType, so we do
+       not crash in methods like MemberLookupFailed that use this field.  
+
+       This problem arises when the compiler fails to resolve a type
+       during interface type definition for example.
+
+2003-02-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Indexers.GetIndexersForType): Interfaces do not
+       inherit from System.Object, so we have to stop at null, not only
+       when reaching System.Object.
+
+2003-02-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: (Indexers.GetIndexersForType): Martin's fix used
+       DeclaredOnly because the parent indexer might have had a different
+       name, but did not loop until the top of the hierarchy was reached.
+
+       The problem this one fixes is 35492: when a class implemented an
+       indexer from an interface, we were getting the interface method
+       (which was abstract) and we were flagging an error (can not invoke
+       abstract method).
+
+       This also keeps bug 33089 functioning, and test-148 functioning.
+
+       * typemanager.cs (IsSpecialMethod): The correct way of figuring
+       out if a method is special is to see if it is declared in a
+       property or event, or whether it is one of the predefined operator
+       names.   This should fix correctly #36804.
+
+2003-02-15  Miguel de Icaza  <miguel@ximian.com>
+
+       The goal here is to remove the dependency on EmptyCast.Peel ().
+       Killing it completely.
+
+       The problem is that currently in a number of places where
+       constants are expected, we have to "probe" for an EmptyCast, and
+       Peel, which is not the correct thing to do, as this will be
+       repetitive and will likely lead to errors. 
+
+       The idea is to remove any EmptyCasts that are used in casts that
+       can be reduced to constants, so we only have to cope with
+       constants. 
+
+       This bug hunt was triggered by Bug 37363 and the desire to remove
+       the duplicate pattern where we were "peeling" emptycasts to check
+       whether they were constants.  Now constants will always be
+       constants.
+
+       * ecore.cs: Use an enumconstant here instead of wrapping with
+       EmptyCast.  
+
+       * expression.cs (Cast.TryReduce): Ah, the tricky EnumConstant was
+       throwing me off.  By handling this we can get rid of a few hacks.
+
+       * statement.cs (Switch): Removed Peel() code.
+
+2003-02-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs: Location information for error 508
+
+       * expression.cs (New.DoResolve): Add a guard against double
+       resolution of an expression.  
+
+       The New DoResolve might be called twice when initializing field
+       expressions (see EmitFieldInitializers, the call to
+       GetInitializerExpression will perform a resolve on the expression,
+       and later the assign will trigger another resolution
+
+       This leads to bugs (#37014)
+
+       * delegate.cs: The signature for EndInvoke should contain any ref
+       or out parameters as well.  We were not doing this in the past. 
+
+       * class.cs (Field.Define): Do not overwrite the type definition
+       inside the `volatile' group.  Turns out that volatile enumerations
+       were changing the type here to perform a validity test, which
+       broke conversions. 
+
+2003-02-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (FieldExpr.AddressOf): In the particular case of This
+       and structs, we do not want to load the instance variable
+
+       (ImplicitReferenceConversion, ImplicitReferenceConversionExists):
+       enum_type has to be handled like an object reference (implicit
+       conversions exists from this to object), but the regular IsClass
+       and IsValueType tests will never return true for this one.
+
+       Also we use TypeManager.IsValueType instead of type.IsValueType,
+       just for consistency with the rest of the code (this is only
+       needed if we ever use the construct exposed by test-180.cs inside
+       corlib, which we dont today).
+
+2003-02-12  Zoltan Varga  <vargaz@freemail.hu>
+
+       * attribute.cs (ApplyAttributes): apply all MethodImplAttributes, not
+       just InternalCall.
+
+2003-02-09  Martin Baulig  <martin@ximian.com>
+
+       * namespace.cs (Namespace..ctor): Added SourceFile argument.
+       (Namespace.DefineNamespaces): New static public method; this is
+       called when we're compiling with debugging to add all namespaces
+       to the symbol file.
+
+       * tree.cs (Tree.RecordNamespace): Added SourceFile argument and
+       pass it to the Namespace's .ctor.
+
+       * symbolwriter.cs (SymbolWriter.OpenMethod): Added TypeContainer
+       and MethodBase arguments; pass the namespace ID to the symwriter;
+       pass the MethodBase instead of the token to the symwriter.
+       (SymbolWriter.DefineNamespace): New method to add a namespace to
+       the symbol file.
+
+2003-02-09  Martin Baulig  <martin@ximian.com>
+
+       * symbolwriter.cs: New file.  This is a wrapper around
+       ISymbolWriter with a cleaner API.  We'll dynamically Invoke()
+       methods here in near future.
+
+2003-02-09  Martin Baulig  <martin@ximian.com>
+
+       * codegen.cs (EmitContext.Mark): Just pass the arguments to
+       ILGenerator.MarkSequencePoint() which are actually used by the
+       symbol writer.
+
+2003-02-09  Martin Baulig  <martin@ximian.com>
+
+       * location.cs (SourceFile): New public sealed class.  This
+       contains the name and an index which is used in the location's token.
+       (Location): Reserve an appropriate number of bits in the token for
+       the source file instead of walking over that list, this gives us a
+       really huge performance improvement when compiling with debugging.
+
+       * driver.cs (Driver.parse, Driver.tokenize_file): Take a
+       `SourceFile' argument instead of a string.
+       (Driver.ProcessFile): Add all the files via Location.AddFile(),
+       but don't parse/tokenize here, we need to generate the list of all
+       source files before we do that.
+       (Driver.ProcessFiles): New static function.  Parses/tokenizes all
+       the files.
+
+       * cs-parser.jay (CSharpParser): Take a `SourceFile' argument
+       instead of a string.
+
+       * cs-tokenizer.cs (Tokenizer): Take `SourceFile' argument instead
+       of a string.
+
+2003-02-09  Martin Baulig  <martin@ximian.com>
+
+       * cs-tokenizer.cs (Tokenizer.PreProcessLine): Also reset the
+       filename on `#line default'.
+
+Sat Feb 8 17:03:16 CET 2003 Paolo Molaro <lupus@ximian.com>
+
+       * statement.cs: don't clear the pinned var when the fixed statement
+       returns from the method (fixes bug#37752).
+
+Sat Feb 8 12:58:06 CET 2003 Paolo Molaro <lupus@ximian.com>
+
+       * typemanager.cs: fix from mathpup@mylinuxisp.com (Marcus Urban) 
+       to IsValueType.
+
+2003-02-07  Martin Baulig  <martin@ximian.com>
+
+       * driver.cs: Removed the `--debug-args' command line argument.
+
+       * codegen.cs (CodeGen.SaveSymbols): Removed, this is now done
+       automatically by the AsssemblyBuilder.
+       (CodeGen.InitializeSymbolWriter): We don't need to call any
+       initialization function on the symbol writer anymore.  This method
+       doesn't take any arguments.
+
+2003-02-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: (AddAssemblyAndDeps, LoadAssembly): Enter the types
+       from referenced assemblies as well.
+
+2003-02-02  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (MethodData.Emit): Generate debugging info for external methods.
+
+2003-02-02  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Constructor.Emit): Open the symbol writer before
+       emitting the constructor initializer.
+       (ConstructorInitializer.Emit): Call ec.Mark() to allow
+       single-stepping through constructor initializers.
+
+2003-01-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs: Handle error 549: do not allow virtual methods in
+       sealed classes. 
+
+2003-02-01 Jackson Harper <jackson@latitudegeo.com>
+
+       * decl.cs: Check access levels when resolving types
+
+2003-01-31 Jackson Harper <jackson@latitudegeo.com>
+
+       * statement.cs: Add parameters and locals set in catch blocks that might 
+       return to set vector
+
+2003-01-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Operator): Set the SpecialName flags for operators.
+
+       * expression.cs (Invocation.DoResolve): Only block calls to
+       accessors and operators on SpecialName methods.
+
+       (Cast.TryReduce): Handle conversions from char constants.
+
+
+Tue Jan 28 17:30:57 CET 2003 Paolo Molaro <lupus@ximian.com>
+
+       * statement.cs: small memory and time optimization in FlowBranching.
+
+2003-01-28  Pedro Mart  <yoros@wanadoo.es>
+
+       * expression.cs (IndexerAccess.DoResolveLValue): Resolve the same
+       problem that the last fix but in the other sid (Set).
+
+       * expression.cs (IndexerAccess.DoResolve): Fix a problem with a null
+       access when there is no indexer in the hierarchy.
+
+2003-01-27 Jackson Harper <jackson@latitudegeo.com>
+
+       * class.cs: Combine some if statements.
+
+2003-01-27  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * driver.cs: fixed bug #37187.
+
+2003-01-27  Pedro Martinez Juliá  <yoros@wanadoo.es>
+
+       * expression.cs (IndexerAccess.DoResolve): Before trying to resolve
+       any indexer, it's needed to build a list with all the indexers in the
+       hierarchy (AllGetters), else we have problems. Fixes #35653.
+
+2003-01-23  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (MethodData.Define): It is wrong for an interface
+       implementation to be static in both cases: explicit and implicit.
+       We were only handling this in one case.
+
+       Improve the if situation there to not have negations.
+
+       * class.cs (Field.Define): Turns out that we do not need to check
+       the unsafe bit on field definition, only on usage.  Remove the test.
+
+2003-01-22  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * driver.cs: use assembly.Location instead of Codebase (the latest
+       patch made mcs fail when using MS assemblies).
+
+2003-01-21  Tim Haynes <thaynes@openlinksw.com>
+
+       * driver.cs: use DirectorySeparatorChar instead of a hardcoded "/" to
+       get the path to *corlib.dll.
+
+2003-01-21  Nick Drochak <ndrochak@gol.com>
+
+       * cs-tokenizer.cs:
+       * pending.cs:
+       * typemanager.cs: Remove compiler warnings
+
+2003-01-20  Duncan Mak  <duncan@ximian.com>
+
+       * AssemblyInfo.cs: Bump the version number to 0.19.
+
+2003-01-20  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * cs-tokenizer.cs: little fixes to line numbering when #line is used.
+
+2003-01-18  Zoltan Varga  <vargaz@freemail.hu>
+
+       * class.cs (Constructor::Emit): Emit debugging info for constructors.
+
+2003-01-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Small fix: we were not comparing the constructor
+       name correctly.   Thanks to Zoltan for the initial pointer.
+
+2003-01-16 Jackson Harper <jackson@latitudegeo.com>
+
+       * cs-tokenizer.cs: Set file name when specified with #line
+
+2003-01-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Only perform the constructor checks here if we
+       are named like the class;  This will help provider a better
+       error.  The constructor path is taken when a type definition is
+       not found, but most likely the user forgot to add the type, so
+       report that rather than the constructor error.
+
+Tue Jan 14 10:36:49 CET 2003 Paolo Molaro <lupus@ximian.com>
+
+       * class.cs, rootcontext.cs: small changes to avoid unnecessary memory
+       allocations.
+
+2003-01-13 Jackson Harper <jackson@latitudegeo.com>
+
+       * cs-parser.jay: Add cleanup call.
+
+2003-01-13  Duncan Mak  <duncan@ximian.com>
+
+       * cs-tokenizer.cs (Cleanup): Rename to 'cleanup' to make it more
+       consistent with other methods.
+
+2003-01-13 Jackson Harper <jackson@latitudegeo.com>
+
+       * cs-tokenizer.cs: Add Cleanup method, also fix #region error messages.
+
+Sun Jan 12 19:58:42 CET 2003 Paolo Molaro <lupus@ximian.com>
+
+       * attribute.cs: only set GuidAttr to true when we have a
+       GuidAttribute.
+
+2003-01-09  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * ecore.cs:
+       * expression.cs:
+       * typemanager.cs: fixes to allow mcs compile corlib with the new
+       Type.IsSubclassOf fix.
+
+2003-01-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (LocalVariableReference.DoResolve): Classify a
+       constant as a value, not as a variable.   Also, set the type for
+       the variable.
+
+       * cs-parser.jay (fixed_statement): take a type instead of a
+       pointer_type, so we can produce a better error message later.
+
+       * statement.cs (Fixed.Resolve): Flag types that are not pointers
+       as an error.  
+
+       (For.DoEmit): Make inifinite loops have a
+       non-conditional branch back.
+
+       (Fixed.DoEmit): First populate the pinned variables, then emit the
+       statement, then clear the variables.  Before I was emitting the
+       code once for each fixed piece.
+
+
+2003-01-08  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (FlowBranching.MergeChild): A break in a
+       SWITCH_SECTION does not leave a loop.  Fixes #36155.
+
+2003-01-08  Martin Baulig  <martin@ximian.com>
+
+       * statement.cs (FlowBranching.CheckOutParameters): `struct_params'
+       lives in the same number space than `param_map'.  Fixes #36154.
+
+2003-01-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay (constructor_declaration): Set the
+       Constructor.ModFlags before probing for it.  This makes the
+       compiler report 514, 515 and 132 (the code was there, but got
+       broken). 
+
+       * statement.cs (Goto.Resolve): Set `Returns' to ALWAYS.
+       (GotoDefault.Resolve): Set `Returns' to ALWAYS.
+       (GotoCase.Resolve): Set `Returns' to ALWAYS.
+
+Tue Jan 7 18:32:24 CET 2003 Paolo Molaro <lupus@ximian.com>
+
+       * enum.cs: create the enum static fields using the enum type.
+
+Tue Jan 7 18:23:44 CET 2003 Paolo Molaro <lupus@ximian.com>
+
+       * class.cs: don't try to create the ParamBuilder for the return
+       type if it's not needed (and handle it breaking for the ms runtime
+       anyway).
+
+2003-01-06 Jackson Harper <jackson@latitudegeo.com>
+
+       * cs-tokenizer.cs: Add REGION flag to #region directives, and add checks to make sure that regions are being poped correctly
+
+2002-12-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs (get_cmd_arg): Fixups to allow \r to terminate
+       the command.   This showed up while compiling the JANET source
+       code, which used \r as its only newline separator.
+
+2002-12-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Method.Define): If we are an operator (because it
+       reuses our code), then set the SpecialName and HideBySig.  #36128
+
+2002-12-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (FieldExpr.DoResolve): Instead of throwing an
+       exception, report error 120 `object reference required'.
+
+       * driver.cs: Add --pause option, used during to measure the size
+       of the process as it goes with --timestamp.
+
+       * expression.cs (Invocation.DoResolve): Do not allow methods with
+       SpecialName to be invoked.
+
+2002-12-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: Small fix to the parser: compute the ascii
+       number before adding it.
+
+2002-12-21  Ravi Pratap  <ravi@ximian.com>
+
+       * ecore.cs (StandardImplicitConversion): When in an unsafe
+       context, we allow conversion between void * to any other pointer
+       type. This fixes bug #35973.
+
+2002-12-20 Jackson Harper <jackson@latitudegeo.com>
+
+       * codegen.cs: Use Path.GetFileNameWithoutExtension so an exception
+       is not thrown when extensionless outputs are used 
+
+2002-12-20  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * rootcontext.cs: fixed compilation of corlib.
+
+2002-12-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs (Attributes.Contains): Add new method.
+
+       * class.cs (MethodCore.LabelParameters): if the parameter is an
+       `out' parameter, check that no attribute `[In]' has been passed.
+
+       * enum.cs: Handle the `value__' name in an enumeration.
+
+2002-12-14  Jaroslaw Kowalski <jarek@atm.com.pl>
+
+       * decl.cs: Added special case to allow overrides on "protected
+       internal" methods
+
+2002-12-18  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (Attributes.AddAttributeSection): Rename to this
+       since it makes much more sense.
+
+       (Attributes.ctor): Don't require a Location parameter.
+
+       * rootcontext.cs (AddGlobalAttributeSection): Rename again.
+
+       * attribute.cs (ApplyAttributes): Remove extra Location parameters
+       since we already have that information per attribute.
+
+       * everywhere : make appropriate changes.
+
+       * class.cs (LabelParameters): Write the code which actually
+       applies attributes to the return type. We can't do this on the MS
+       .NET runtime so we flag a warning in the case an exception is
+       thrown.
+
+2002-12-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * const.cs: Handle implicit null conversions here too.
+
+2002-12-17  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (MethodCore.LabelParameters): Remove the extra
+       Type [] parameter since it is completely unnecessary. Instead
+       pass in the method's attributes so that we can extract
+       the "return" attribute.
+
+2002-12-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay (parse): Use Report.Error to flag errors instead
+       of ignoring it and letting the compile continue.
+
+       * typemanager.cs (ChangeType): use an extra argument to return an
+       error condition instead of throwing an exception.
+
+2002-12-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Unary.TryReduce): mimic the code for the regular
+       code path.  Perform an implicit cast in the cases where we can
+       implicitly convert to one of the integral types, and then reduce
+       based on that constant.   This fixes bug #35483.
+
+2002-12-14  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * typemanager.cs: fixed cut & paste error in GetRemoveMethod.
+
+2002-12-13  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * namespace.cs: fixed bug #35489.
+
+2002-12-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs: Remove some dead code.
+
+       * cs-parser.jay: Estimate the number of methods needed
+       (RootContext.MethodCount);
+
+       * cs-tokenizer.cs: Use char arrays for parsing identifiers and
+       numbers instead of StringBuilders.
+
+       * support.cs (PtrHashtable): Add constructor with initial size;
+       We can now reduce reallocations of the method table.
+
+2002-12-10  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (ApplyAttributes): Keep track of the emitted
+       attributes on a per-target basis. This fixes bug #35413.
+
+2002-12-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs (MainDriver): On rotor encoding 28591 does not exist,
+       default to the Windows 1252 encoding.
+
+       (UnixParseOption): Support version, thanks to Alp for the missing
+       pointer. 
+
+       * AssemblyInfo.cs: Add nice assembly information.
+
+       * cs-tokenizer.cs: Add fix from Felix to the #if/#else handler
+       (bug 35169).
+
+       * cs-parser.jay: Allow a trailing comma before the close bracked
+       in the attribute_section production.
+
+       * ecore.cs (FieldExpr.AddressOf): Until I figure out why the
+       address of the instance was being taken, I will take this out,
+       because we take the address of the object immediately here.
+
+2002-12-09  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (AreMultipleAllowed): Take care of the most
+       obvious case where attribute type is not in the current assembly -
+       stupid me ;-)
+
+2002-12-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (SimpleName.DoResolve): First perform lookups on using
+       definitions, instead of doing that afterwards.  
+
+       Also we use a nice little hack, depending on the constructor, we
+       know if we are a "composed" name or a simple name.  Hence, we
+       avoid the IndexOf test, and we avoid 
+
+       * codegen.cs: Add code to assist in a bug reporter to track down
+       the source of a compiler crash. 
+
+2002-12-07  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (Attribute.ApplyAttributes) : Keep track of which attribute
+       types have been emitted for a given element and flag an error
+       if something which does not have AllowMultiple set is used more
+       than once.
+
+       * typemanager.cs (RegisterAttributeAllowMultiple): Keep track of
+       attribute types and their corresponding AllowMultiple properties
+
+       (AreMultipleAllowed): Check the property for a given type.
+
+       * attribute.cs (Attribute.ApplyAttributes): Register the AllowMultiple
+       property in the case we have a TypeContainer.
+
+       (Attributes.AddAttribute): Detect duplicates and just skip on
+       adding them. This trivial fix catches a pretty gross error in our
+       attribute emission - global attributes were being emitted twice!
+
+       Bugzilla bug #33187 is now fixed.
+
+2002-12-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs (pp_expr): Properly recurse here (use pp_expr
+       instead of pp_and).
+
+       * expression.cs (Binary.ResolveOperator): I can only use the
+       Concat (string, string, string) and Concat (string, string,
+       string, string) if the child is actually a concatenation of
+       strings. 
+
+2002-12-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: Small fix, because decimal_digits is used in a
+       context where we need a 2-character lookahead.
+
+       * pending.cs (PendingImplementation): Rework so we can keep track
+       of interface types all the time, and flag those which were
+       implemented by parents as optional.
+
+2002-12-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Binary.ResolveOperator): Use
+       String.Concat(string,string,string) or
+       String.Concat(string,string,string,string) when possible. 
+
+       * typemanager: More helper methods.
+
+
+Tue Dec 3 19:32:04 CET 2002 Paolo Molaro <lupus@ximian.com>
+
+       * pending.cs: remove the bogus return from GetMissingInterfaces()
+       (see the 2002-11-06 entry: the mono runtime is now fixed in cvs).
+
+2002-12-02  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * namespace.cs: avoid duplicated 'using xxx' being added to
+       using_clauses. This prevents mcs from issuing and 'ambiguous type' error
+       when we get more than one 'using' statement for the same namespace.
+       Report a CS0105 warning for it.
+
+2002-11-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs (consume_identifier): use read directly, instead
+       of calling getChar/putback, uses internal knowledge of it.    
+
+       (xtoken): Reorder tokenizer so most common patterns are checked
+       first.  This reduces the compilation time in another 5% (from 8.11s
+       average to 7.73s for bootstrapping mcs on my Mobile p4/1.8ghz).
+
+       The parsing time is 22% of the compilation in mcs, and from that
+       64% is spent on the tokenization process.  
+
+       I tried using a binary search for keywords, but this is slower
+       than the hashtable.  Another option would be to do a couple of
+       things:
+
+               * Not use a StringBuilder, instead use an array of chars,
+                 with a set value.  Notice that this way we could catch
+                 the 645 error without having to do it *afterwards*.
+
+               * We could write a hand-parser to avoid the hashtable
+                 compares altogether.
+
+       The identifier consumption process takes 37% of the tokenization
+       time.  Another 15% is spent on is_number.  56% of the time spent
+       on is_number is spent on Int64.Parse:
+
+               * We could probably choose based on the string length to
+                 use Int32.Parse or Int64.Parse and avoid all the 64-bit
+                 computations. 
+
+       Another 3% is spend on wrapping `xtoken' in the `token' function.
+
+       Handle 0xa0 as whitespace (#34752)
+
+2002-11-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (IsCLRType): New routine to tell whether a type
+       is one of the builtin types.  
+
+       Maybe it needs to use TypeCodes to be faster.  Maybe we could use
+       typecode in more places instead of doing pointer comparissions.
+       We could leverage some knowledge about the way the typecodes are
+       laid out.
+
+       New code to cache namespaces in assemblies, it is currently not
+       invoked, to be used soon.
+
+       * decl.cs (DeclSpace.MakeFQN): Simple optimization.
+
+       * expression.cs (Binary.ResolveOperator): specially handle
+       strings, and do not perform user-defined operator overloading for
+       built-in types.
+
+2002-11-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: Avoid calling Char.IsDigit which is an
+       internalcall as it is a pretty simple operation;  Avoid whenever
+       possible to call Char.IsLetter.
+
+       (consume_identifier): Cut by half the number of
+       hashtable calls by merging the is_keyword and GetKeyword behavior.
+
+       Do not short-circuit, because if we do, we
+       report errors (ie, #if false && true would produce an invalid
+       directive error);
+
+
+2002-11-24  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Cast.TryReduce): If we're in checked syntax,
+       check constant ranges and report a CS0221.  Fixes #33186.
+
+2002-11-24  Martin Baulig  <martin@ximian.com>
+
+       * cs-parser.jay: Make this work for uninitialized variable
+       declarations in the `for' initializer.  Fixes #32416.
+
+2002-11-24  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (Expression.ConvertExplicit): Make casting from/to
+       System.Enum actually work.  Fixes bug #32269, added verify-6.cs.
+
+2002-11-24  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Binary.DoNumericPromotions): Added `check_user_conv'
+       argument; if true, we also check for user-defined conversions.
+       This is only needed if both arguments are of a user-defined type.
+       Fixes #30443, added test-175.cs.
+       (Binary.ForceConversion): Pass the location argument to ConvertImplicit.
+
+       * ecore.cs (Expression.ImplicitUserConversionExists): New method.
+
+2002-11-24  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (ArrayAccess.GetStoreOpcode): New public static
+       function to get the store opcode.
+       (Invocation.EmitParams): Call ArrayAccess.GetStoreOpcode() and
+       only emit the Ldelema if the store opcode is Stobj.  You must run
+       both test-34 and test-167 to test this.  Fixes #34529.
+
+2002-11-23  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (Expression.MemberLookup): Added additional
+       `qualifier_type' argument which is used when we're being called
+       from MemberAccess.DoResolve() and null if we're called from a
+       SimpleName lookup.
+       (Expression.MemberLookupFailed): New method to report errors; this
+       does the CS1540 check and reports the correct error message.
+
+       * typemanager.cs (MemberLookup): Added additional `qualifier_type'
+       argument for the CS1540 check and redone the way how we're dealing
+       with private members.  See the comment in the source code for details.
+       (FilterWithClosure): Reverted this back to revision 1.197; renamed
+       `closure_start_type' to `closure_qualifier_type' and check whether
+       it's not null.  It was not this filter being broken, it was just
+       being called with the wrong arguments.
+
+       * expression.cs (MemberAccess.DoResolve): use MemberLookupFinal()
+       and pass it the correct `qualifier_type'; this also does the error
+       handling for us.
+
+2002-11-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Invocation.EmitParams): If the we are dealing
+       with a non-built-in value type, load its address as well.
+
+       (ArrayCreation): Use a a pretty constant instead
+       of the hardcoded value 2.   Use 6 instead of 2 for the number of
+       static initializers.  
+
+       (ArrayCreation.EmitDynamicInitializers): Peel enumerations,
+       because they are not really value types, just glorified integers. 
+
+       * driver.cs: Do not append .exe, the CSC compiler does not do it.
+
+       * ecore.cs: Remove redundant code for enumerations, make them use
+       the same code path as everything else, fixes the casting issue
+       with enumerations in Windows.Forms.
+
+       * attribute.cs: Do only cast to string if it is a string, the
+       validation happens later.
+
+       * typemanager.cs: Temproary hack to avoid a bootstrap issue until
+       people upgrade their corlibs.
+
+       * ecore.cs: Oops, enumerations were not following the entire code path
+
+2002-11-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (FilterWithClosure): Commented out the test for
+       1540 in typemanager.cs, as it has problems when accessing
+       protected methods from a parent class (see test-174.cs). 
+
+       * attribute.cs (Attribute.ValidateGuid): new method.
+       (Attribute.Resolve): Use above.
+
+2002-11-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * enum.cs: In FindMembers, perform a recursive lookup for values. (34308)
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Remove the special
+       handling for enumerations, as we only needed the TypeContainer
+       functionality to begin with (this is required for the fix below to
+       work for enums that reference constants in a container class for
+       example). 
+
+       * codegen.cs (EmitContext): Make TypeContainer a DeclSpace.
+
+       * enum.cs (Enum.Define): Use `this' instead of parent, so we have
+       a valid TypeBuilder to perform lookups on.o
+
+       * class.cs (InheritableMemberSignatureCompare): Use true in the
+       call to GetGetMethod and GetSetMethod, because we are comparing
+       the signature, and we need to get the methods *even* if they are
+       private. 
+
+       (PropertyBase.CheckBase): ditto.
+
+       * statement.cs (Switch.ResolveAndReduce, Block.EmitMeta,
+       GotoCase.Resolve): Use Peel on EmpytCasts.
+
+       * ecore.cs (EmptyCast): drop child, add Peel method.
+
+2002-11-17  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (EmptyCast.Child): New public property.
+
+       * statement.cs (SwitchLabel.ResolveAndReduce): Check whether the
+       label resolved to an EmptyCast.  Fixes #34162.
+       (GotoCase.Resolve): Likewise.
+       (Block.EmitMeta): Likewise.
+
+2002-11-17  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Invocation.BetterConversion): Prefer int over
+       uint; short over ushort; long over ulong for integer literals.
+       Use ImplicitConversionExists instead of StandardConversionExists
+       since we also need to check for user-defined implicit conversions.
+       Fixes #34165.  Added test-173.cs.
+
+2002-11-16  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (Binary.EmitBranchable): Eliminate comparisions
+       with the `true' and `false' literals.  Fixes #33151.
+
+2002-11-16  Martin Baulig  <martin@ximian.com>
+
+       * typemanager.cs (RealMemberLookup): Reverted Miguel's patch from
+       October 22nd; don't do the cs1540 check for static members.
+
+       * ecore.cs (PropertyExpr.ResolveAccessors): Rewrote this; we're
+       now using our own filter here and doing the cs1540 check again.
+
+2002-11-16  Martin Baulig  <martin@ximian.com>
+
+       * support.cs (InternalParameters): Don't crash if we don't have
+       any fixed parameters.  Fixes #33532.
+
+2002-11-16  Martin Baulig  <martin@ximian.com>
+
+       * decl.cs (MemberCache.AddMethods): Use BindingFlags.FlattenHierarchy
+       when looking up static methods to make this work on Windows.
+       Fixes #33773.
+
+2002-11-16  Martin Baulig  <martin@ximian.com>
+
+       * ecore.cs (PropertyExpr.VerifyAssignable): Check whether we have
+       a setter rather than using PropertyInfo.CanWrite.
+
+2002-11-15  Nick Drochak  <ndrochak@gol.com>
+
+       * class.cs: Allow acces to block member by subclasses. Fixes build
+       breaker.
+
+2002-11-14  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (Constructor.Emit): Added the extern/block check.
+       Fixes bug #33678.
+
+2002-11-14  Martin Baulig  <martin@ximian.com>
+
+       * expression.cs (IndexerAccess.DoResolve): Do a DeclaredOnly
+       iteration while looking for indexers, this is needed because the
+       indexer may have a different name in our base classes.  Fixed the
+       error reporting (no indexers at all, not get accessor, no
+       overloaded match).  Fixes bug #33089.
+       (IndexerAccess.DoResolveLValue): Likewise.
+
+2002-11-14  Martin Baulig  <martin@ximian.com>
+
+       * class.cs (PropertyBase.CheckBase): Make this work for multiple
+       indexers.  Fixes the first part of bug #33089.
+       (MethodSignature.InheritableMemberSignatureCompare): Added support
+       for properties.
+
+2002-11-13  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (Attribute.Resolve): Catch the
+       NullReferenceException and report it since it isn't supposed to
+       happen. 
+
+2002-11-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Binary.EmitBranchable): Also handle the cases for
+       LogicalOr and LogicalAnd that can benefit from recursively
+       handling EmitBranchable.  The code now should be nice for Paolo.
+
+2002-11-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (LookupType): Added a negative-hit hashtable for
+       the Type lookups, as we perform quite a number of lookups on
+       non-Types.  This can be removed once we can deterministically tell
+       whether we have a type or a namespace in advance.
+
+       But this might require special hacks from our corlib.
+
+       * TODO: updated.
+
+       * ecore.cs (TryImplicitIntConversion): Handle conversions to float
+       and double which avoids a conversion from an integer to a double.
+
+       * expression.cs: tiny optimization, avoid calling IsConstant,
+       because it effectively performs the lookup twice.
+
+2002-11-06  Miguel de Icaza  <miguel@ximian.com>
+
+       But a bogus return here to keep the semantics of the old code
+       until the Mono runtime is fixed.
+
+       * pending.cs (GetMissingInterfaces): New method used to remove all
+       the interfaces that are already implemented by our parent
+       classes from the list of pending methods. 
+
+       * interface.cs: Add checks for calls after ResolveTypeExpr.
+
+2002-11-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Class.Emit): Report warning 67: event not used if the
+       warning level is beyond 3.
+
+       * ecore.cs (Expression.ConvertExplicit): Missed a check for expr
+       being a NullLiteral.
+
+       * cs-parser.jay: Fix, Gonzalo reverted the order of the rank
+       specifiers. 
+
+       * class.cs (TypeContainer.GetClassBases): Cover a missing code
+       path that might fail if a type can not be resolved.
+
+       * expression.cs (Binary.Emit): Emit unsigned versions of the
+       operators. 
+
+       * driver.cs: use error 5.
+
+2002-11-02  Gonzalo Paniagua Javier <gonzalo@gnome-db.org>
+
+       * cs-parser.jay: simplified a rule and 5 SR conflicts dissapeared.
+
+2002-11-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay (switch_section): A beautiful patch from Martin
+       Baulig that fixed 33094.
+
+2002-10-31  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (PropertyExpr.DoResolveLValue, PropertyExpr.DoResolve):
+       Check whether the base is abstract and report an error if so.
+
+       * expression.cs (IndexerAccess.DoResolveLValue,
+       IndexerAccess.DoResolve): ditto. 
+
+       (Invocation.DoResolve): ditto.
+
+       (Invocation.FullMethodDesc): Improve the report string.
+
+       * statement.cs (Block): Eliminate IsVariableDefined as it is
+       basically just a wrapper for GetVariableInfo.
+
+       * ecore.cs (SimpleName): Use new 
+
+       * support.cs (ReflectionParamter.ParameterType): We unwrap the
+       type, as we return the actual parameter ref/unref state on a
+       different call.
+
+2002-10-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * support.cs: Return proper flags REF/OUT fixing the previous
+       commit.  
+
+       * expression.cs: Reverted last patch, that was wrong.  Is_ref is
+       not used to mean `ref' but `ref or out' in ParameterReference
+
+       * delegate.cs (FullDelegateDesc): use ParameterDesc to get the
+       full type signature instead of calling TypeManger.CSharpName
+       ourselves. 
+
+       * support.cs (InternalParameters.ParameterDesc): Do not compare
+       directly to the modflags, because REF/OUT will actually be bitsets
+       if set. 
+
+       * delegate.cs (VerifyMethod): Check also the modifiers.
+
+       * cs-tokenizer.cs: Fix bug where floating point values with an
+       exponent where a sign was missing was ignored.
+
+       * driver.cs: Allow multiple assemblies to be specified in a single
+       /r: argument
+
+2002-10-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Ugly.  We had to add a multiplicative_expression,
+       because identifiers after a parenthesis would end up in this kind
+       of production, and we needed to desamiguate it for having casts
+       like:
+
+               (UserDefinedType *) xxx
+
+2002-10-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (RealMemberLookup): when we deal with a subclass,
+       we should set on the Bindingflags.NonPublic, but not turn on
+       private_ok.  private_ok controls whether a Private member is
+       returned (this is chekced on the filter routine), while the
+       BindingFlags.NonPublic just controls whether private/protected
+       will be allowed.   This fixes the problem part of the problem of
+       private properties being allowed to be used in derived classes.
+
+       * expression.cs (BaseAccess): Provide an DoResolveLValue method,
+       so we can call the children DoResolveLValue method (this will
+       properly signal errors on lvalue assignments to base properties)
+
+       * ecore.cs (PropertyExpr.ResolveAccessors): If both setter and
+       getter are null, and we have a property info, we know that this
+       happened because the lookup failed, so we report an error 122 for
+       protection level violation.
+
+       We also silently return if setter and getter are null in the
+       resolve functions, this condition only happens if we have flagged
+       the error before.  This is the other half of the problem. 
+
+       (PropertyExpr.ResolveAccessors): Turns out that PropertyInfo does
+       not have accessibility information, that is why we were returning
+       true in the filter function in typemanager.cs.
+
+       To properly report 122 (property is inaccessible because of its
+       protection level) correctly, we report this error in ResolveAccess
+       by failing if both the setter and the getter are lacking (ie, the
+       lookup failed). 
+
+       DoResolve and DoLResolve have been modified to check for both
+       setter/getter being null and returning silently, the reason being
+       that I did not want to put the knowledge about this error in upper
+       layers, like:
+
+       int old = Report.Errors;
+       x = new PropertyExpr (...);
+       if (old != Report.Errors)
+               return null;
+       else
+               return x;
+
+       So the property expr is returned, but it is invalid, so the error
+       will be flagged during the resolve process. 
+
+       * class.cs: Remove InheritablePropertySignatureCompare from the
+       class, as we no longer depend on the property signature to compute
+       whether it is possible to implement a method or not.
+
+       The reason is that calling PropertyInfo.GetGetMethod will return
+       null (in .NET, in Mono it works, and we should change this), in
+       cases where the Get Method does not exist in that particular
+       class.
+
+       So this code:
+
+       class X { public virtual int A { get { return 1; } } }
+       class Y : X { }
+       class Z : Y { public override int A { get { return 2; } } }
+
+       Would fail in Z because the parent (Y) would not have the property
+       defined.  So we avoid this completely now (because the alternative
+       fix was ugly and slow), and we now depend exclusively on the
+       method names.
+
+       (PropertyBase.CheckBase): Use a method-base mechanism to find our
+       reference method, instead of using the property.
+
+       * typemanager.cs (GetPropertyGetter, GetPropertySetter): These
+       routines are gone now.
+
+       * typemanager.cs (GetPropertyGetter, GetPropertySetter): swap the
+       names, they were incorrectly named.
+
+       * cs-tokenizer.cs: Return are more gentle token on failure. 
+
+       * pending.cs (PendingImplementation.InterfaceMethod): This routine
+       had an out-of-sync index variable, which caused it to remove from
+       the list of pending methods the wrong method sometimes.
+
+2002-10-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (PropertyExpr): Do not use PropertyInfo.CanRead,
+       CanWrite, because those refer to this particular instance of the
+       property, and do not take into account the fact that we can
+       override single members of a property.
+
+       Constructor requires an EmitContext.  The resolution process does
+       not happen here, but we need to compute the accessors before,
+       because the resolution does not always happen for properties.
+
+       * typemanager.cs (RealMemberLookup): Set private_ok if we are a
+       subclass, before we did not update this flag, but we did update
+       bindingflags. 
+
+       (GetAccessors): Drop this routine, as it did not work in the
+       presence of partially overwritten set/get methods. 
+
+       Notice that this broke the cs1540 detection, but that will require
+       more thinking. 
+
+2002-10-22  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * class.cs:
+       * codegen.cs:
+       * driver.cs: issue a warning instead of an error if we don't support
+       debugging for the platform. Also ignore a couple of errors that may
+       arise when trying to write the symbols. Undo my previous patch.
+
+2002-10-22  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * driver.cs: ignore /debug switch except for Unix platforms.
+
+2002-10-23  Nick Drochak  <ndrochak@gol.com>
+
+       * makefile: Remove mcs2.exe and mcs3.exe on 'make clean'
+
+2002-10-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Do not make mcs-debug conditional, so we do not break
+       builds that use it.
+
+       * statement.cs (UsageVector.MergeChildren): I would like Martin to
+       review this patch.  But basically after all the children variables
+       have been merged, the value of "Breaks" was not being set to
+       new_breaks for Switch blocks.  I think that it should be set after
+       it has executed.  Currently I set this to the value of new_breaks,
+       but only if new_breaks is FlowReturn.ALWAYS, which is a bit
+       conservative, but I do not understand this code very well.
+
+       I did not break anything in the build, so that is good ;-)
+
+       * cs-tokenizer.cs: Also allow \r in comments as a line separator.
+
+2002-10-20  Mark Crichton  <crichton@gimp.org>
+
+       * cfold.cs: Fixed compile blocker.  Really fixed it this time.
+
+2002-10-20  Nick Drochak  <ndrochak@gol.com>
+
+       * cfold.cs: Fixed compile blocker.
+
+2002-10-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: I was chekcing the key, not the file.
+
+2002-10-19  Ravi Pratap  <ravi@ximian.com>
+
+       * ecore.cs (UserDefinedConversion): Get rid of the bogus error
+       message that we were generating - we just need to silently return
+       a null.
+
+2002-10-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Event.Define): Change my previous commit, as this
+       breaks the debugger.  This is a temporary hack, as it seems like
+       the compiler is generating events incorrectly to begin with.
+
+       * expression.cs (Binary.ResolveOperator): Added support for 
+       "U operator - (E x, E y)"
+
+       * cfold.cs (BinaryFold): Added support for "U operator - (E x, E
+       y)".
+
+       * ecore.cs (FieldExpr.AddressOf): We had a special code path for
+       init-only variables, but this path did not take into account that
+       there might be also instance readonly variables.  Correct this
+       problem. 
+
+       This fixes bug 32253
+
+       * delegate.cs (NewDelegate.DoResolve): Catch creation of unsafe
+       delegates as well.
+
+       * driver.cs: Change the extension for modules to `netmodule'
+
+       * cs-parser.jay: Improved slightly the location tracking for
+       the debugger symbols.
+
+       * class.cs (Event.Define): Use Modifiers.FieldAttr on the
+       modifiers that were specified instead of the hardcoded value
+       (FamAndAssem).  This was basically ignoring the static modifier,
+       and others.  Fixes 32429.
+
+       * statement.cs (Switch.SimpleSwitchEmit): Simplified the code, and
+       fixed a bug in the process (32476)
+
+       * expression.cs (ArrayAccess.EmitAssign): Patch from
+       hwang_rob@yahoo.ca that fixes bug 31834.3
+
+2002-10-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Make the module extension .netmodule.
+
+2002-10-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Report an error if the resource file is not found
+       instead of crashing.
+
+       * ecore.cs (PropertyExpr.EmitAssign): Pass IsBase instead of
+       false, like Emit does.
+
+2002-10-16  Nick Drochak  <ndrochak@gol.com>
+
+       * typemanager.cs: Remove unused private member.  Also reported mcs
+       bug to report this as a warning like csc.
+
+2002-10-15  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Statement.Emit): Made this a virtual method; emits
+       the line number info and calls DoEmit().
+       (Statement.DoEmit): New protected abstract method, formerly knows
+       as Statement.Emit().
+
+       * codegen.cs (EmitContext.Mark): Check whether we have a symbol writer.
+
+2002-10-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs: Following the comment from 2002-09-26 to AddMethod, I
+       have fixed a remaining problem: not every AddXXXX was adding a
+       fully qualified name.  
+
+       Now everyone registers a fully qualified name in the DeclSpace as
+       being defined instead of the partial name.  
+
+       Downsides: we are slower than we need to be due to the excess
+       copies and the names being registered this way.  
+
+       The reason for this is that we currently depend (on the corlib
+       bootstrap for instance) that types are fully qualified, because
+       we dump all the types in the namespace, and we should really have
+       types inserted into the proper namespace, so we can only store the
+       basenames in the defined_names array.
+
+2002-10-10  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (ArrayAccess.EmitStoreOpcode): Reverted the patch
+       from bug #31834, see the bug report for a testcase which is
+       miscompiled.
+
+2002-10-10  Martin Baulig  <martin@gnome.org>
+
+       * codegen.cs (EmitContext.Breaks): Removed, we're now using the
+       flow analysis code for this.
+
+       * statement.cs (Do, While, For): Tell the flow analysis code about
+       infinite loops.
+       (FlowBranching.UsageVector): Added support for infinite loops.
+       (Block.Resolve): Moved the dead code elimination here and use flow
+       analysis to do it.
+
+2002-10-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Field.Define): Catch cycles on struct type
+       definitions. 
+
+       * typemanager.cs (IsUnmanagedtype): Do not recursively check
+       fields if the fields are static.  We only need to check instance
+       fields. 
+
+       * expression.cs (As.DoResolve): Test for reference type.
+
+       * statement.cs (Using.ResolveExpression): Use
+       ConvertImplicitRequired, not ConvertImplicit which reports an
+       error on failture
+       (Using.ResolveLocalVariableDecls): ditto.
+
+       * expression.cs (Binary.ResolveOperator): Report errors in a few
+       places where we had to.
+
+       * typemanager.cs (IsUnmanagedtype): Finish implementation.
+
+2002-10-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Use StoreFromPtr instead of extracting the type
+       and then trying to use Stelem.  Patch is from hwang_rob@yahoo.ca
+
+       * ecore.cs (ImplicitReferenceConversion): It is possible to assign
+       an enumeration value to a System.Enum, but System.Enum is not a
+       value type, but an class type, so we need to box.
+
+       (Expression.ConvertExplicit): One codepath could return
+       errors but not flag them.  Fix this.  Fixes #31853
+
+       * parameter.cs (Resolve): Do not allow void as a parameter type.
+
+2002-10-06  Martin Baulig  <martin@gnome.org>
+
+       * statemenc.cs (FlowBranching.SetParameterAssigned): Don't crash
+       if it's a class type and not a struct.  Fixes #31815.
+
+2002-10-06  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs: Reworked the flow analysis code a bit to make it
+       usable for dead code elimination.
+
+2002-10-06  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * cs-parser.jay: allow empty source files. Fixes bug #31781.
+
+2002-10-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ComposedCast.DoResolveType): A quick workaround
+       to fix the test 165, will investigate deeper.
+
+2002-10-04  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (FlowBranching.UsageVector.MergeChildren): Make
+       finally blocks actually work.
+       (Try.Resolve): We don't need to create a sibling for `finally' if
+       there is no finally block.
+
+2002-10-04  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (Constructor.Define): The default accessibility for a
+       non-default constructor is private, not public.
+
+2002-10-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Constructor): Make AllowedModifiers public, add
+       EXTERN.
+
+       * cs-parser.jay: Perform the modifiers test here, as the
+       constructor for the Constructor class usually receives a zero
+       because of the way we create it (first we create, later we
+       customize, and we were never checking the modifiers).
+
+       * typemanager.cs (Typemanager.LookupTypeDirect): This new function
+       is a version of LookupTypeReflection that includes the type-name
+       cache.  This can be used as a fast path for functions that know
+       the fully qualified name and are only calling into *.GetType() to
+       obtain a composed type.
+
+       This is also used by TypeManager.LookupType during its type
+       composition.
+
+       (LookupType): We now also track the real type name, as sometimes
+       we can get a quey for the real type name from things like
+       ComposedCast.  This fixes bug 31422.
+
+       * expression.cs (ComposedCast.Resolve): Since we are obtaining a
+       complete type fullname, it does not have to go through the type
+       resolution system to obtain the composed version of the type (for
+       obtaining arrays or pointers).
+
+       (Conditional.Emit): Use the EmitBoolExpression to
+       generate nicer code, as requested by Paolo.
+
+       (ArrayCreation.CheckIndices): Use the patch from
+       hwang_rob@yahoo.ca to validate the array initializers. 
+
+2002-10-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (ConstructorInitializer.Emit): simplify code by using
+       Invocation.EmitCall, and at the same time, fix the bugs in calling
+       parent constructors that took variable arguments. 
+
+       * ecore.cs (Expression.ConvertNumericExplicit,
+       Expression.ImplicitNumericConversion): Remove the code that
+       manually wrapped decimal (InternalTypeConstructor call is now gone
+       as well).
+
+       * expression.cs (Cast.TryReduce): Also handle decimal types when
+       trying to perform a constant fold on the type.
+
+       * typemanager.cs (IsUnmanagedtype): Partially implemented.
+
+       * parameter.cs: Removed ResolveAndDefine, as it was not needed, as
+       that only turned off an error report, and did nothing else. 
+
+2002-10-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Handle and ignore /fullpaths
+
+2002-10-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Binary.ResolveOperator): Catch the case where
+       DoNumericPromotions returns true, 
+
+       (Binary.DoNumericPromotions): Simplify the code, and the tests.
+
+2002-09-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (EventExpr.Emit): Instead of emitting an exception,
+       report error 70.
+
+2002-09-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (ConvertNumericExplicit): It is not enough that the
+       conversion exists, but it is also required that the conversion be
+       performed.  This manifested in "(Type64Enum) 2".  
+
+       * class.cs (TypeManager.AddMethod): The fix is not to change
+       AddEnum, because that one was using a fully qualified name (every
+       DeclSpace derivative does), but to change the AddMethod routine
+       that was using an un-namespaced name.  This now correctly reports
+       the duplicated name.
+
+       Revert patch until I can properly fix it.  The issue
+       is that we have a shared Type space across all namespaces
+       currently, which is wrong.
+
+       Options include making the Namespace a DeclSpace, and merge
+       current_namespace/current_container in the parser.
+
+2002-09-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Improve error reporting when we get a different
+       kind of expression in local_variable_type and
+       local_variable_pointer_type. 
+
+       Propagate this to avoid missleading errors being reported.
+
+       * ecore.cs (ImplicitReferenceConversion): treat
+       TypeManager.value_type as a target just like object_type.   As
+       code like this:
+
+       ValueType v = 1;
+
+       Is valid, and needs to result in the int 1 being boxed before it
+       is assigned to the value type v.
+
+       * class.cs (TypeContainer.AddEnum): Use the basename, not the name
+       to validate the enumeration name.
+
+       * expression.cs (ArrayAccess.EmitAssign): Mimic the same test from
+       EmitDynamicInitializers for the criteria to use Ldelema.  Thanks
+       to hwang_rob@yahoo.ca for finding the bug and providing a patch.
+
+       * ecore.cs (TryImplicitIntConversion): When doing an
+       implicit-enumeration-conversion, check if the type is 64-bits and
+       perform a conversion before passing to EnumConstant.
+
+2002-09-23  Miguel de Icaza  <miguel@ximian.com>
+
+       * decl.cs (Error_AmbiguousTypeReference); New routine used to
+       report ambiguous type references.  Unlike the MS version, we
+       report what the ambiguity is.   Innovation at work ;-)
+
+       (DeclSpace.FindType): Require a location argument to
+       display when we display an ambiguous error.
+
+       * ecore.cs: (SimpleName.DoResolveType): Pass location to FindType.
+
+       * interface.cs (GetInterfaceTypeByName): Pass location to FindType.
+
+       * expression.cs (EmitDynamicInitializers): Apply patch from
+       hwang_rob@yahoo.ca that fixes the order in which we emit our
+       initializers. 
+
+2002-09-21  Martin Baulig  <martin@gnome.org>
+
+       * delegate.cs (Delegate.VerifyApplicability): Make this work if the
+       delegate takes no arguments.
+
+2002-09-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * constant.cs: Use Conv_U8 instead of Conv_I8 when loading longs
+       from integers.
+
+       * expression.cs: Extract the underlying type.
+
+       * ecore.cs (StoreFromPtr): Use TypeManager.IsEnumType instad of IsEnum
+
+       * decl.cs (FindType): Sorry about this, fixed the type lookup bug.
+
+2002-09-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer.DefineType): We can not use the nice
+       PackingSize with the size set to 1 DefineType method, because it
+       will not allow us to define the interfaces that the struct
+       implements.
+
+       This completes the fixing of bug 27287
+
+       * ecore.cs (Expresion.ImplicitReferenceConversion): `class-type S'
+       means also structs.  This fixes part of the problem. 
+       (Expresion.ImplicitReferenceConversionExists): ditto.
+
+       * decl.cs (DeclSparce.ResolveType): Only report the type-not-found
+       error if there were no errors reported during the type lookup
+       process, to avoid duplicates or redundant errors.  Without this
+       you would get an ambiguous errors plus a type not found.  We have
+       beaten the user enough with the first error.  
+
+       (DeclSparce.FindType): Emit a warning if we have an ambiguous
+       reference. 
+
+       * ecore.cs (SimpleName.DoResolveType): If an error is emitted
+       during the resolution process, stop the lookup, this avoids
+       repeated error reports (same error twice).
+
+       * rootcontext.cs: Emit a warning if we have an ambiguous reference.
+
+       * typemanager.cs (LookupType): Redo the type lookup code to match
+       the needs of System.Reflection.  
+
+       The issue is that System.Reflection requires references to nested
+       types to begin with a "+" sign instead of a dot.  So toplevel
+       types look like: "NameSpace.TopLevelClass", and nested ones look
+       like "Namespace.TopLevelClass+Nested", with arbitrary nesting
+       levels. 
+
+2002-09-19  Martin Baulig  <martin@gnome.org>
+
+       * codegen.cs (EmitContext.EmitTopBlock): If control flow analysis
+       says that a method always returns or always throws an exception,
+       don't report the CS0161.
+
+       * statement.cs (FlowBranching.UsageVector.MergeChildren): Always
+       set `Returns = new_returns'.
+
+2002-09-19  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (MemberAccess.ResolveMemberAccess): When resolving
+       to an enum constant, check for a CS0176.
+
+2002-09-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer.CheckPairedOperators): Now we check
+       for operators that must be in pairs and report errors.
+
+       * ecore.cs (SimpleName.DoResolveType): During the initial type
+       resolution process, when we define types recursively, we must
+       check first for types in our current scope before we perform
+       lookups in the enclosing scopes.
+
+       * expression.cs (MakeByteBlob): Handle Decimal blobs.
+
+       (Invocation.VerifyArgumentsCompat): Call
+       TypeManager.TypeToCoreType on the parameter_type.GetElementType.
+       I thought we were supposed to always call this, but there are a
+       few places in the code where we dont do it.
+
+2002-09-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Add support in -linkres and -resource to specify the
+       name of the identifier.
+
+2002-09-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (StandardConversionExists): Sync with the conversion
+       code: allow anything-* to void* conversions.
+
+       (FindMostSpecificSource): Use an Expression argument
+       instead of a Type, because we might be handed over a Literal which
+       gets a few more implicit conversions that plain types do not.  So
+       this information was being lost.
+
+       Also, we drop the temporary type-holder expression when not
+       required.
+
+2002-09-17  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (PropertyBase.CheckBase): Don't check the base class if
+       this is an explicit interface implementation.
+
+2002-09-17  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (PropertyBase.CheckBase): Make this work for indexers with
+       different `IndexerName' attributes.
+
+       * expression.cs (BaseIndexerAccess): Rewrote this class to use IndexerAccess.
+       (IndexerAccess): Added special protected ctor for BaseIndexerAccess and
+       virtual CommonResolve().
+
+2002-09-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * enum.cs (LookupEnumValue): Use the EnumConstant declared type,
+       and convert that to the UnderlyingType.
+
+       * statement.cs (Foreach.Resolve): Indexers are just like variables
+       or PropertyAccesses.
+
+       * cs-tokenizer.cs (consume_string): Track line numbers and columns
+       inside quoted strings, we were not doing this before.
+
+2002-09-16  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (MethodGroupExpr.DoResolve): If we have an instance expression,
+       resolve it.  This is needed for the definite assignment check of the
+       instance expression, fixes bug #29846.
+       (PropertyExpr.DoResolve, EventExpr.DoResolve): Likewise.
+
+2002-09-16  Nick Drochak  <ndrochak@gol.com>
+
+       * parameter.cs: Fix compile error.  Cannot reference static member
+       from an instance object.  Is this an mcs bug?
+
+2002-09-14  Martin Baulig  <martin@gnome.org>
+
+       * decl.cs (MemberCache.SetupCacheForInterface): Don't add an interface
+       multiple times.  Fixes bug #30295, added test-166.cs.
+
+2002-09-14  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Block.Emit): Don't emit unreachable code.
+       (Switch.SimpleSwitchEmit, Switch.TableSwitchEmit): Check for missing
+       `break' statements.
+       (Goto.Emit, Continue.Emit): Set ec.Breaks = true.
+
+2002-09-14  Martin Baulig  <martin@gnome.org>
+
+       * parameter.cs (Parameter.Attributes): Make this work if Modifier.ISBYREF
+       is set.
+
+2002-09-14  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.IsNestedChildOf): This must return false
+       if `type == parent' since in this case `type.IsSubclassOf (parent)' will
+       be false on the ms runtime.
+
+2002-09-13  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Include the member name in
+       the CS0038 error message.
+
+2002-09-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (CheckedExpr, UnCheckedExpr): If we have a
+       constant inside, return it.
+
+2002-09-12  Martin Baulig  <martin@gnome.org>
+
+       * cfold.cs (ConstantFold.DoConstantNumericPromotions): Check whether an
+       implicit conversion can be done between enum types.
+
+       * enum.cs (Enum.LookupEnumValue): If the value is an EnumConstant,
+       check whether an implicit conversion to the current enum's UnderlyingType
+       exists and report an error if not.
+
+       * codegen.cs (CodeGen.Init): Delete the symbol file when compiling
+       without debugging support.
+
+       * delegate.cs (Delegate.CloseDelegate): Removed, use CloseType instead.
+       Fixes bug #30235.  Thanks to Ricardo Fernández Pascual.
+
+2002-09-12  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.IsNestedChildOf): New method.
+
+       * ecore.cs (IMemberExpr.DeclaringType): New property.
+       (SimpleName.SimpleNameResolve): Check whether we're accessing a
+       nonstatic member of an outer type (CS0038).
+
+2002-09-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Activate the using-error detector at warning level
+       4 (at least for MS-compatible APIs).
+
+       * namespace.cs (VerifyUsing): Small buglett fix.
+
+       * pending.cs (PendingImplementation): pass the container pointer. 
+
+       * interface.cs (GetMethods): Allow for recursive definition.  Long
+       term, I would like to move every type to support recursive
+       definitions, not the current ordering mechanism that we have right
+       now.
+
+       The situation is this: Attributes are handled before interfaces,
+       so we can apply attributes to interfaces.  But some attributes
+       implement interfaces, we will now handle the simple cases
+       (recursive definitions will just get an error).  
+
+       * parameter.cs: Only invalidate types at the end if we fail to
+       lookup all types.  
+
+2002-09-09  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (PropertyExpr.Emit): Also check for
+       TypeManager.system_int_array_get_length so this'll also work when
+       compiling corlib.  Fixes #30003.
+
+2002-09-09  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (ArrayCreation.MakeByteBlob): Added support for enums
+       and throw an exception if we can't get the type's size.  Fixed #30040,
+       added test-165.cs.
+
+2002-09-09  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (PropertyExpr.DoResolve): Added check for static properies.
+
+       * expression.cs (SizeOf.DoResolve): Sizeof is only allowed in unsafe
+       context.  Fixes bug #30027.
+
+       * delegate.cs (NewDelegate.Emit): Use OpCodes.Ldvirtftn for
+       virtual functions.  Fixes bug #30043, added test-164.cs.
+
+2002-09-08  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs : Fix a small NullRef crash thanks to my stupidity.
+
+2002-09-08  Nick Drochak  <ndrochak@gol.com>
+
+       * driver.cs: Use an object to get the windows codepage since it's not a
+       static property.
+
+2002-09-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (For.Emit): for infinite loops (test == null)
+       return whether there is a break inside, not always "true".
+
+       * namespace.cs (UsingEntry): New struct to hold the name of the
+       using definition, the location where it is defined, and whether it
+       has been used in a successful type lookup.
+
+       * rootcontext.cs (NamespaceLookup): Use UsingEntries instead of
+       strings.
+
+       * decl.cs: ditto.
+
+2002-09-06  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs : Fix incorrect code which relied on catching
+       a NullReferenceException to detect a null being passed in
+       where an object was expected.
+
+2002-09-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Try): flag the catch variable as assigned
+
+       * expression.cs (Cast): Simplified by using ResolveType instead of
+       manually resolving.
+
+       * statement.cs (Catch): Fix bug by using ResolveType.
+
+2002-09-06  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (BetterConversion): Special case for when we have
+       a NullLiteral as the argument and we have to choose between string
+       and object types - we choose string the way csc does.
+
+       * attribute.cs (Attribute.Resolve): Catch the
+       NullReferenceException and report error #182 since the Mono
+       runtime no more has the bug and having this exception raised means
+       we tried to select a constructor which takes an object and is
+       passed a null.
+
+2002-09-05  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Invocation.OverloadResolve): Flag a nicer error
+       message (1502, 1503) when we can't locate a method after overload
+       resolution. This is much more informative and closes the bug
+       Miguel reported.
+
+       * interface.cs (PopulateMethod): Return if there are no argument
+       types. Fixes a NullReferenceException bug.
+
+       * attribute.cs (Attribute.Resolve): Ensure we allow TypeOf
+       expressions too. Previously we were checking only in one place for
+       positional arguments leaving out named arguments.
+
+       * ecore.cs (ImplicitNumericConversion): Conversion from underlying
+       type to the enum type is not allowed. Remove code corresponding to
+       that.
+
+       (ConvertNumericExplicit): Allow explicit conversions from
+       the underlying type to enum type. This precisely follows the spec
+       and closes a bug filed by Gonzalo.
+
+2002-09-04  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * compiler.csproj:
+       * compiler.csproj.user: patch from Adam Chester (achester@bigpond.com).
+
+2002-09-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (SwitchLabel.ResolveAndReduce): In the string case,
+       it was important that we stored the right value after the
+       reduction in `converted'.
+
+2002-09-04  Martin Baulig  <martin@gnome.org>
+
+       * location.cs (Location.SymbolDocument): Use full pathnames for the
+       source files.
+
+2002-08-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ComposedCast): Use DeclSparce.ResolveType instead
+       of the expression resolve mechanism, because that will catch the
+       SimpleName error failures.
+
+       (Conditional): If we can not resolve the
+       expression, return, do not crash.
+
+2002-08-29  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * cs-tokenizer.cs:
+       (location): display token name instead of its number.
+
+2002-08-28  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Binary.ResolveOperator): Don't silently return
+       but return an error if an operator cannot be applied between two
+       enum types.
+
+2002-08-28  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (Constructor.Define): Set the permission attributes
+       correctly instead of making all constructors public.
+
+2002-08-28  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.DoResolve): Do a TypeManager.MemberLook
+       for private members before reporting a CS0103; if we find anything,
+       it's a CS0122.
+
+2002-08-28  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.FilterWithClosure): It's not enough
+       to check whether `closure_start_type == closure_invocation_type',
+       we also need to check whether `m.DeclaringType == closure_invocation_type'
+       before bypassing the permission checks.  We might be accessing
+       protected/private members from the base class.
+       (TypeManager.RealMemberLookup): Only set private_ok if private
+       members were requested via BindingFlags.NonPublic.
+
+       * ecore.cs (MethodGroupExpr.IsExplicitImpl): New property.
+
+       * expression.cs (MemberAccess.ResolveMemberAccess): Set
+       MethodGroupExpr.IsExplicitImpl if appropriate.
+       (Invocation.DoResolve): Don't report the CS0120 for explicit
+       interface implementations.
+
+2002-08-27  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Invocation.DoResolve): If this is a static
+       method and we don't have an InstanceExpression, we must report
+       a CS0120.
+
+2002-08-25  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Binary.ResolveOperator): Don't allow `!=' and
+       `==' between a valuetype and an object.
+
+2002-08-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (TypeExpr): Provide a ToString method.
+
+2002-08-24  Martin Baulig  <martin@gnome.org>
+
+       * codegen.cs (CodeGen.InitMonoSymbolWriter): The symbol file is
+       now called proggie.dbg and it's a binary file.
+
+2002-08-23  Martin Baulig  <martin@gnome.org>
+
+       * decl.cs (MemberCache.AddMethods): Ignore varargs methods.
+
+2002-08-23  Martin Baulig  <martin@gnome.org>
+
+       * struct.cs (MyStructInfo.ctor): Make this work with empty
+       structs; it's not allowed to use foreach() on null.
+
+2002-08-23  Martin Baulig  <martin@gnome.org>
+
+       * codegen.cs (CodeGen.InitMonoSymbolWriter): Tell the symbol
+       writer the full pathname of the generated assembly.
+
+2002-08-23  Martin Baulig  <martin@gnome.org>
+
+       * statements.cs (FlowBranching.UsageVector.MergeChildren):
+       A `finally' block never returns or breaks; improved handling of
+       unreachable code.
+
+2002-08-23  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Throw.Resolve): Allow `throw null'.
+
+2002-08-23  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (MemberAccess.ResolveMemberAccess): If this is an
+       EventExpr, don't do a DeclaredOnly MemberLookup, but check whether
+       `ee.EventInfo.DeclaringType == ec.ContainerType'.  The
+       MemberLookup would return a wrong event if this is an explicit
+       interface implementation and the class has an event with the same
+       name.
+
+2002-08-23  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Block.AddChildVariableNames): New public method.
+       (Block.AddChildVariableName): Likewise.
+       (Block.IsVariableNameUsedInChildBlock): Likewise.
+       (Block.AddVariable): Check whether a variable name has already
+       been used in a child block.
+
+       * cs-parser.jay (declare_local_variables): Mark all variable names
+       from the current block as being used in a child block in the
+       implicit block.
+
+2002-08-23  Martin Baulig  <martin@gnome.org>
+
+       * codegen.cs (CodeGen.InitializeSymbolWriter): Abort if we can't
+       find the symbol writer.
+
+       * driver.cs: csc also allows the arguments to /define being
+       separated by commas, not only by semicolons.
+
+2002-08-23  Martin Baulig  <martin@gnome.org>
+
+       * interface.cs (Interface.GetMembers): Added static check for events.
+
+2002-08-15  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (MethodData.EmitDestructor): In the Expression.MemberLookup
+       call, use ec.ContainerType.BaseType as queried_type and invocation_type.
+
+       * ecore.cs (Expression.MemberLookup): Added documentation and explained
+       why the MethodData.EmitDestructor() change was necessary.
+
+2002-08-20  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (TypeContainer.FindMembers): Added static check for events.
+
+       * decl.cs (MemberCache.AddMembers): Handle events like normal members.
+
+       * typemanager.cs (TypeHandle.GetMembers): When queried for events only,
+       use Type.GetEvents(), not Type.FindMembers().
+
+2002-08-20  Martin Baulig  <martin@gnome.org>
+
+       * decl.cs (MemberCache): Added a special method cache which will
+       be used for method-only searched.  This ensures that a method
+       search will return a MethodInfo with the correct ReflectedType for
+       inherited methods.      
+
+2002-08-20  Martin Baulig  <martin@gnome.org>
+
+       * decl.cs (DeclSpace.FindMembers): Made this public.
+
+2002-08-20  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * delegate.cs: fixed build on windows.
+       [FIXME:  Filed as bug #29150: MCS must report these errors.]
+
+2002-08-19  Ravi Pratap  <ravi@ximian.com>
+
+       * ecore.cs (StandardConversionExists): Return a false
+       if we are trying to convert the void type to anything else
+       since that is not allowed.
+
+       * delegate.cs (DelegateInvocation.DoResolve): Ensure that
+       we flag error 70 in the event an event is trying to be accessed
+       directly from outside the declaring type.
+
+2002-08-20  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs, decl.cs: Moved MemberList, IMemberContainer and
+       MemberCache from typemanager.cs to decl.cs.
+
+2002-08-19  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (TypeContainer): Implement IMemberContainer.
+       (TypeContainer.DefineMembers): Create the MemberCache.
+       (TypeContainer.FindMembers): Do better BindingFlags checking; only
+       return public members if BindingFlags.Public was given, check
+       whether members are static.
+
+2002-08-16  Martin Baulig  <martin@gnome.org>
+
+       * decl.cs (DeclSpace.Define): Splitted this in Define and
+       DefineMembers.  DefineMembers is called first and initializes the
+       MemberCache.
+
+       * rootcontext.cs (RootContext.DefineMembers): New function.  Calls
+       DefineMembers() on all our DeclSpaces.
+
+       * class.cs (TypeContainer.Define): Moved all code to DefineMembers(),
+       but call DefineMembers() on all nested interfaces.  We call their
+       Define() in our new Define() function.
+
+       * interface.cs (Interface): Implement IMemberContainer.
+       (Interface.Define): Moved all code except the attribute stuf to
+       DefineMembers().
+       (Interface.DefineMembers): Initialize the member cache.
+
+       * typemanager.cs (IMemberFinder): Removed this interface, we don't
+       need this anymore since we can use MemberCache.FindMembers directly.
+
+2002-08-19  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (MemberCache): When creating the cache for an
+       interface type, add all inherited members.
+       (TypeManager.MemberLookup_FindMembers): Changed `ref bool searching'
+       to `out bool used_cache' and documented it.
+       (TypeManager.MemberLookup): If we already used the cache in the first
+       iteration, we don't need to do the interfaces check.
+
+2002-08-19  Martin Baulig  <martin@gnome.org>
+
+       * decl.cs (DeclSpace.FindMembers): New abstract method.  Moved this
+       here from IMemberFinder and don't implement this interface anymore.
+       (DeclSpace.MemberCache): Moved here from IMemberFinder.
+
+       * typemanager.cs (IMemberFinder): This interface is now only used by
+       classes which actually support the member cache.
+       (TypeManager.builder_to_member_finder): Renamed to builder_to_declspace
+       since we only put DeclSpaces into this Hashtable.
+       (MemberLookup_FindMembers): Use `builder_to_declspace' if the type is
+       a dynamic type and TypeHandle.GetTypeHandle() otherwise.
+
+2002-08-16  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (ICachingMemberFinder): Removed.
+       (IMemberFinder.MemberCache): New property.
+       (TypeManager.FindMembers): Merged this with RealFindMembers().
+       This function will never be called from TypeManager.MemberLookup()
+       so we can't use the cache here, just the IMemberFinder.
+       (TypeManager.MemberLookup_FindMembers): Check whether the
+       IMemberFinder has a MemberCache and call the cache's FindMembers
+       function.
+       (MemberCache): Rewrote larger parts of this yet another time and
+       cleaned it up a bit.
+
+2002-08-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs (LoadArgs): Support quoting.
+
+       (Usage): Show the CSC-like command line arguments.
+
+       Improved a few error messages.
+
+2002-08-15  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (IMemberContainer.Type): New property.
+       (IMemberContainer.IsInterface): New property.
+
+       The following changes are conditional to BROKEN_RUNTIME, which is
+       defined at the top of the file.
+
+       * typemanager.cs (MemberCache.MemberCache): Don't add the base
+       class'es members, but add all members from TypeHandle.ObjectType
+       if we're an interface.
+       (MemberCache.AddMembers): Set the Declared flag if member.DeclaringType
+       is the current type.
+       (MemberCache.CacheEntry.Container): Removed this field.
+       (TypeHandle.GetMembers): Include inherited members.
+
+2002-08-14  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * typemanager.cs: fixed compilation and added a comment on a field that
+       is never used.
+
+2002-08-15  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (ConstructorInitializer.Resolve): In the
+       Expression.MemberLookup call, use the queried_type as
+       invocation_type.
+
+       * typemanager.cs (IMemberContainer.GetMembers): Removed the `bool
+       declared' attribute, it's always true.
+       (IMemberContainer.Parent, IMemberContainer.Name): New properties.
+       (TypeManager.MemberLookup_FindMembers): [FIXME FIXME FIXME] Added
+       temporary wrapper for FindMembers which tells MemberLookup whether
+       members from the base classes are included in the return value.
+       This will go away soon.
+       (TypeManager.MemberLookup): Use this temporary hack here; once the
+       new MemberCache is completed, we don't need to do the DeclaredOnly
+       looping here anymore since the MemberCache will take care of this.
+       (TypeManager.IsSubclassOrNestedChildOf): Allow `type == parent'.
+       (MemberCache): When creating the MemberCache for a class, get
+       members from the current class and all its base classes.
+       (MemberCache.CacheEntry.Container): New field.  This is a
+       temporary hack until the Mono runtime is fixed to distinguish
+       between ReflectedType and DeclaringType.  It allows us to use MCS
+       with both the MS runtime and the unfixed Mono runtime without
+       problems and without accecting performance.
+       (MemberCache.SearchMembers): The DeclaredOnly looping from
+       TypeManager.MemberLookup is now done here.      
+
+2002-08-14  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (MyStructInfo.MyStructInfo): Don't call
+       Type.GetFields on dynamic types but get the fields from the
+       corresponding TypeContainer.
+       (MyStructInfo.GetStructInfo): Added check for enum types.
+
+       * typemanager.cs (MemberList.IsSynchronized): Implemented.
+       (MemberList.SyncRoot): Implemented.
+       (TypeManager.FilterWithClosure): No need to check permissions if
+       closure_start_type == closure_invocation_type, don't crash if
+       closure_invocation_type is null.
+
+2002-08-13  Martin Baulig  <martin@gnome.org>
+
+       Rewrote TypeContainer.FindMembers to use a member cache.  This
+       gives us a speed increase of about 35% for the self-hosting MCS
+       build and of about 15-20% for the class libs (both on GNU/Linux).
+
+       * report.cs (Timer): New class to get enhanced profiling.  This
+       whole class is "TIMER" conditional since it remarkably slows down
+       compilation speed.
+
+       * class.cs (MemberList): New class.  This is an IList wrapper
+       which we're now using instead of passing MemberInfo[]'s around to
+       avoid copying this array unnecessarily.
+       (IMemberFinder.FindMember): Return a MemberList, not a MemberInfo [].
+       (ICachingMemberFinder, IMemberContainer): New interface.
+       (TypeManager.FilterWithClosure): If `criteria' is null, the name
+       has already been checked, otherwise use it for the name comparision.
+       (TypeManager.FindMembers): Renamed to RealMemberFinder and
+       provided wrapper which tries to use ICachingMemberFinder.FindMembers
+       if possible.  Returns a MemberList, not a MemberInfo [].
+       (TypeHandle): New class, implements IMemberContainer.  We create
+       one instance of this class per type, it contains a MemberCache
+       which is used to do the member lookups.
+       (MemberCache): New class.  Each instance of this class contains
+       all members of a type and a name-based hash table.
+       (MemberCache.FindMembers): This is our new member lookup
+       function.  First, it looks up all members of the requested name in
+       the hash table.  Then, it walks this list and sorts out all
+       applicable members and returns them.
+
+2002-08-13  Martin Baulig  <martin@gnome.org>
+
+       In addition to a nice code cleanup, this gives us a performance
+       increase of about 1.4% on GNU/Linux - not much, but it's already
+       half a second for the self-hosting MCS compilation.
+
+       * typemanager.cs (IMemberFinder): New interface.  It is used by
+       TypeManager.FindMembers to call FindMembers on a TypeContainer,
+       Enum, Delegate or Interface.
+       (TypeManager.finder_to_member_finder): New PtrHashtable.
+       (TypeManager.finder_to_container): Removed.
+       (TypeManager.finder_to_delegate): Removed.
+       (TypeManager.finder_to_interface): Removed.
+       (TypeManager.finder_to_enum): Removed.
+
+       * interface.cs (Interface): Implement IMemberFinder.
+
+       * delegate.cs (Delegate): Implement IMemberFinder.
+
+       * enum.cs (Enum): Implement IMemberFinder.
+
+       * class.cs (TypeContainer): Implement IMemberFinder.
+
+2002-08-12  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (TypeExpr.DoResolveType): Mark this as virtual.
+
+2002-08-12  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (ITypeExpression): New interface for expressions which
+       resolve to a type.
+       (TypeExpression): Renamed to TypeLookupExpression.
+       (Expression.DoResolve): If we're doing a types-only lookup, the
+       expression must implement the ITypeExpression interface and we
+       call DoResolveType() on it.
+       (SimpleName): Implement the new ITypeExpression interface.
+       (SimpleName.SimpleNameResolve): Removed the ec.OnlyLookupTypes
+       hack, the situation that we're only looking up types can't happen
+       anymore when this method is called.  Moved the type lookup code to
+       DoResolveType() and call it.
+       (SimpleName.DoResolveType): This ITypeExpression interface method
+       is now doing the types-only lookup.
+       (TypeExpr, TypeLookupExpression): Implement ITypeExpression.
+       (ResolveFlags): Added MaskExprClass.
+
+       * expression.cs (MemberAccess): Implement the ITypeExpression
+       interface.
+       (MemberAccess.DoResolve): Added support for a types-only lookup
+       when we're called via ITypeExpression.DoResolveType().
+       (ComposedCast): Implement the ITypeExpression interface.
+
+       * codegen.cs (EmitContext.OnlyLookupTypes): Removed.  Call
+       Expression.Resolve() with ResolveFlags.Type instead.
+
+2002-08-12  Martin Baulig  <martin@gnome.org>
+
+       * interface.cs (Interface.Define): Apply attributes.
+
+       * attribute.cs (Attribute.ApplyAttributes): Added support for
+       interface attributes.
+
+2002-08-11  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Block.Emit): Only check the "this" variable if we
+       do not always throw an exception.
+
+       * ecore.cs (PropertyExpr.DoResolveLValue): Implemented, check
+       whether the property has a set accessor.
+
+2002-08-11  Martin Baulig  <martin@gnome.org>
+
+       Added control flow analysis support for structs.
+
+       * ecore.cs (ResolveFlags): Added `DisableFlowAnalysis' to resolve
+       with control flow analysis turned off.
+       (IVariable): New interface.
+       (SimpleName.SimpleNameResolve): If MemberAccess.ResolveMemberAccess
+       returns an IMemberExpr, call DoResolve/DoResolveLValue on it.
+       (FieldExpr.DoResolve): Resolve the instance expression with flow
+       analysis turned off and do the definite assignment check after the
+       resolving when we know what the expression will resolve to.
+
+       * expression.cs (LocalVariableReference, ParameterReference):
+       Implement the new IVariable interface, only call the flow analysis
+       code if ec.DoFlowAnalysis is true.
+       (This): Added constructor which takes a Block argument.  Implement
+       the new IVariable interface.
+       (MemberAccess.DoResolve, MemberAccess.DoResolveLValue): Call
+       DoResolve/DoResolveLValue on the result of ResolveMemberLookup().
+       This does the definite assignment checks for struct members.
+
+       * class.cs (Constructor.Emit): If this is a non-static `struct'
+       constructor which doesn't have any initializer, call
+       Block.AddThisVariable() to tell the flow analysis code that all
+       struct elements must be initialized before control returns from
+       the constructor.
+
+       * statement.cs (MyStructInfo): New public class.
+       (UsageVector.this [VariableInfo vi]): Added `int field_idx'
+       argument to this indexer.  If non-zero, check an individual struct
+       member, not the whole struct.
+       (FlowBranching.CheckOutParameters): Check struct members.
+       (FlowBranching.IsVariableAssigned, SetVariableAssigned): Added
+       overloaded versions of these methods which take an additional
+       `int field_idx' argument to check struct members.
+       (FlowBranching.IsParameterAssigned, SetParameterAssigned): Added
+       overloaded versions of these methods which take an additional
+       `string field_name' argument to check struct member.s
+       (VariableInfo): Implement the IVariable interface.
+       (VariableInfo.StructInfo): New public property.  Returns the
+       MyStructInfo instance of the variable if it's a struct or null.
+       (Block.AddThisVariable): New public method.  This is called from
+       Constructor.Emit() for non-static `struct' constructor which do
+       not have any initializer.  It creates a special variable for the
+       "this" instance variable which will be checked by the flow
+       analysis code to ensure that all of the struct's fields are
+       initialized before control returns from the constructor.
+       (UsageVector): Added support for struct members.  If a
+       variable/parameter is a struct with N members, we reserve a slot
+       in the usage vector for each member.  A struct is considered fully
+       initialized if either the struct itself (slot 0) or all its
+       members are initialized.
+
+2002-08-08  Martin Baulig  <martin@gnome.org>
+
+       * driver.cs (Driver.MainDriver): Only report an error CS5001
+       if there were no compilation errors.
+
+       * codegen.cs (EmitContext.EmitContext): Use the DeclSpace's
+       `UnsafeContext' property to determine whether the parent is in
+       unsafe context rather than checking the parent's ModFlags:
+       classes nested in an unsafe class are unsafe as well.
+
+2002-08-08  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (UsageVector.MergeChildren): Distinguish between
+       `Breaks' and `Returns' everywhere, don't set `Breaks' anymore if
+       we return.  Added test17() and test18() to test-154.cs.
+
+2002-08-08  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.FilterWithClosure): If we have
+       Family access, make sure the invoking type isn't a subclass of the
+       queried type (that'd be a CS1540).
+
+       * ecore.cs (Expression.MemberLookup): Added overloaded version of
+       this method which takes an additional `Type invocation_type'.
+
+       * expression.cs (BaseAccess.DoResolve): Use the base type as
+       invocation and query type.
+       (MemberAccess.DoResolve): If the lookup failed and we're about to
+       report a CS0122, try a lookup with the ec.ContainerType - if this
+       succeeds, we must report a CS1540.
+
+2002-08-08  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (IMemberExpr): Added `bool IsInstance' property.
+       (MethodGroupExpr): Implement the IMemberExpr interface.
+
+       * expression (MemberAccess.ResolveMemberAccess): No need to have
+       any special code for MethodGroupExprs anymore, they're now
+       IMemberExprs.   
+
+2002-08-08  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.FilterWithClosure): Check Assembly,
+       Family, FamANDAssem and FamORAssem permissions.
+       (TypeManager.IsSubclassOrNestedChildOf): New public method.
+
+2002-08-08  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (FlowBranchingType): Added LOOP_BLOCK.
+       (UsageVector.MergeChildren): `break' breaks unless we're in a switch
+       or loop block.
+
+Thu Aug 8 10:28:07 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * driver.cs: implemented /resource option to embed managed resources.
+
+2002-08-07  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (FieldBase.Initializer): Renamed to `init' and made private.
+       (FieldBase.HasFieldInitializer): New public property.
+       (FieldBase.GetInitializerExpression): New public method.  Resolves and
+       returns the field initializer and makes sure it is only resolved once.
+       (TypeContainer.EmitFieldInitializers): Call
+       FieldBase.GetInitializerExpression to get the initializer, this ensures
+       that it isn't resolved multiple times.
+
+       * codegen.cs (EmitContext): Added `bool IsFieldInitialier'.  This tells
+       the resolving process (SimpleName/MemberLookup) that we're currently
+       emitting a field initializer (which must not access any instance members,
+       this is an error CS0236).
+
+       * ecore.cs (SimpleName.Error_ObjectRefRequired): Added EmitContext
+       argument, if the `IsFieldInitializer' flag is set, we must report and
+       error CS0236 and not an error CS0120.   
+
+2002-08-07  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (IMemberExpr): New public interface.
+       (FieldExpr, PropertyExpr, EventExpr): Implement IMemberExpr.
+       (SimpleName.SimpleNameResolve): Call MemberAccess.ResolveMemberAccess
+       if the expression is an IMemberExpr.
+
+       * expression.cs (MemberAccess.ResolveMemberAccess): Allow `left'
+       to be null, implicitly default to `this' if we're non-static in
+       this case.  Simplified the code a lot by using the new IMemberExpr
+       interface.  Also fixed bug #28176 here.
+
+2002-08-06  Martin Baulig  <martin@gnome.org>
+
+       * cs-parser.jay (SimpleLookup): Removed.  We need to create
+       ParameterReferences during semantic analysis so that we can do a
+       type-only search when resolving Cast, TypeOf and SizeOf.
+       (block): Pass the `current_local_parameters' to the Block's
+       constructor.
+
+       * class.cs (ConstructorInitializer): Added `Parameters parameters'
+       argument to the constructor.
+       (ConstructorInitializer.Resolve): Create a temporary implicit
+       block with the parameters.
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Resolve parameter
+       references here if we aren't doing a type-only search.
+
+       * statement.cs (Block): Added constructor which takes a
+       `Parameters parameters' argument.
+       (Block.Parameters): New public property.
+
+       * support.cs (InternalParameters.Parameters): Renamed `parameters'
+       to `Parameters' and made it public readonly.
+
+2002-08-06  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.Warning): Made this public as well.
+
+       * report.cs (Report.Debug): Print the contents of collections.
+
+2002-08-06  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.ResolveFlags): New [Flags] enum.  This is
+       used to tell Resolve() which kinds of expressions it may return.
+       (Expression.Resolve): Added overloaded version of this method which
+       takes a `ResolveFlags flags' argument.  This can be used to tell
+       Resolve() which kinds of expressions it may return.  Reports a
+       CS0118 on error.
+       (Expression.ResolveWithSimpleName): Removed, use Resolve() with
+       ResolveFlags.SimpleName.
+       (Expression.Error118): Added overloaded version of this method which
+       takes a `ResolveFlags flags' argument.  It uses the flags to determine
+       which kinds of expressions are allowed.
+
+       * expression.cs (Argument.ResolveMethodGroup): New public method.
+       Resolves an argument, but allows a MethodGroup to be returned.
+       This is used when invoking a delegate.
+
+       * TODO: Updated a bit.
+
+2002-08-06  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       Fixed compilation with csc.
+
+       * ecore.cs: Expression.Error made public. Is this correct? Should
+       Warning be made public too?
+
+       * expression.cs: use ea.Location instead of ea.loc.
+       [FIXME:  Filed as bug #28607: MCS must report these errors.]
+
+2002-08-06  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.loc): Moved the location here instead of
+       duplicating it in all derived classes.
+       (Expression.Location): New public property.
+       (Expression.Error, Expression.Warning): Made them non-static and
+       removed the location argument.
+       (Expression.Warning): Added overloaded version which takes an
+       `int level' argument.
+       (Expression.Error118): Make this non-static and removed the
+       expression and location arguments.
+       (TypeExpr): Added location argument to the constructor.
+
+       * expression.cs (StaticCallExpr): Added location argument to
+       the constructor.
+       (Indirection, PointerArithmetic): Likewise.
+       (CheckedExpr, UnCheckedExpr): Likewise.
+       (ArrayAccess, IndexerAccess, UserCast, ArrayPtr): Likewise.
+       (StringPtr): Likewise.
+
+
+2002-08-05  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (BaseAccess.DoResolve): Actually report errors.
+
+       * assign.cs (Assign.DoResolve): Check whether the source
+       expression is a value or variable.
+
+       * statement.cs (Try.Resolve): Set ec.InTry/InCatch/InFinally
+       while resolving the corresponding blocks.
+
+       * interface.cs (Interface.GetInterfaceTypeByName): Actually report
+       an error, don't silently return null.
+
+       * statement.cs (Block.AddVariable): Do the error reporting here
+       and distinguish between CS0128 and CS0136.
+       (Block.DoResolve): Report all unused labels (warning CS0164).
+       (LabeledStatement): Pass the location to the constructor.
+       (LabeledStatement.HasBeenReferenced): New property.
+       (LabeledStatement.Resolve): Set it to true here.
+
+       * statement.cs (Return.Emit): Return success even after reporting
+       a type mismatch error (CS0126 or CS0127), this is what csc does and
+       it avoids confusing the users with any consecutive errors.
+
+2002-08-05  Martin Baulig  <martin@gnome.org>
+
+       * enum.cs (Enum.LookupEnumValue): Catch circular definitions.
+
+       * const.cs (Const.LookupConstantValue): Catch circular definitions.
+
+       * expression.cs (MemberAccess.DoResolve): Silently return if an
+       error has already been reported.
+
+       * ecore.cs (Expression.MemberLookupFinal): Silently return if an
+       error has already been reported.
+
+2002-08-05  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (UsageVector): Only initialize the `parameters'
+       vector if we actually have any "out" parameters.
+
+2002-08-05  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Binary.ResolveOperator): When combining delegates,
+       they must have the same type.
+
+2002-08-05  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.GetArgumentTypes): Don't call
+       PropertyInfo.GetIndexParameters() on dynamic types, this doesn't
+       work with the ms runtime and we also don't need it: if we're a
+       PropertyBuilder and not in the `indexer_arguments' hash, then we
+       are a property and not an indexer.
+
+       * class.cs (TypeContainer.AsAccessible): Use Type.IsArray,
+       Type.IsPointer and Type.IsByRef instead of Type.HasElementType
+       since the latter one doesn't work with the ms runtime.
+
+2002-08-03  Martin Baulig  <martin@gnome.org>
+
+       Fixed bugs #27998 and #22735.
+
+       * class.cs (Method.IsOperator): New public field.
+       (Method.CheckBase): Report CS0111 if there's already a method
+       with the same parameters in the current class.  Report CS0508 when
+       attempting to change the return type of an inherited method.
+       (MethodData.Emit): Report CS0179 if a method doesn't have a body
+       and it's not marked abstract or extern.
+       (PropertyBase): New abstract base class for Property and Indexer.
+       (PropertyBase.CheckBase): Moved here from Property and made it work
+       for indexers.
+       (PropertyBase.Emit): Moved here from Property.Emit, Indexer.Emit is
+       the same so we can reuse it there.
+       (Property, Indexer): Derive from PropertyBase.
+       (MethodSignature.inheritable_property_signature_filter): New delegate
+       to find properties and indexers.
+
+       * decl.cs (MemberCore.CheckMethodAgainstBase): Added `string name'
+       argument and improved error reporting.
+
+       * parameter.cs (Parameters.GetEmptyReadOnlyParameters): Renamed to
+       EmptyReadOnlyParameters and made it a property.
+
+       * typemanager.cs (TypeManager.GetArgumentTypes): Added overloaded
+       version of this method which takes a `PropertyInfo indexer'.
+       (TypeManager.RegisterIndexer): New method.
+
+       * class.cs: Added myself as author of this file :-)
+
+2002-08-03  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * class.cs: fixed compilation on windoze.
+
+2002-08-03  Martin Baulig  <martin@gnome.org>
+
+       * interface.cs (Interface.GetInterfaceBases): Check whether all
+       base interfaces are at least as accessible than the current one.
+
+       * class.cs (TypeContainer.GetClassBases): Check whether base types
+       are at least as accessible than the current type.
+       (TypeContainer.AsAccessible): Implemented and made non-static.
+       (MemberBase.CheckParameters): Report errors if the accessibility
+       checks fail.
+
+       * delegate.cs (Delegate.Delegate): The default visibility is
+       internal for top-level types and private for nested types.
+       (Delegate.Define): Report errors if the accessibility checks fail.
+
+       * enum.cs (Enum.Enum): The default visibility is internal for
+       top-level types and private for nested types.
+       (Enum.DefineType): Compute the correct visibility.
+
+       * modifiers.cs (Modifiers.TypeAttr): Added a version of this
+       function which takes a `bool is_toplevel' instead of a TypeContainer.
+
+       * typemanager.cs (TypeManager.IsBuiltinType): `void' is also a
+       builtin type.
+
+2002-08-02  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (LocalVariableReferenc): Added constructor which
+       takes additional `VariableInfo vi' and `bool is_readonly' arguments.
+       (LocalVariableReference.IsReadOnly): New property.
+       (LocalVariableReference.DoResolveLValue): Report a CS1604 if the
+       variable is readonly, use our own readonly flag to do this; you can
+       use the new constructor to get a writable reference to a read-only
+       variable.
+
+       * cs-parser.jay (foreach_statement, using_statement): Get a writable
+       reference to the local variable.
+
+2002-08-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs (ResolveCore): Also include System.Exception
+
+       * statement.cs (Block.Emit): Do not emit the dead-code warnings if
+       we reach an EmptyStatement.
+
+       (Catch.DoResolve, Throw.DoResolve): Throwing the System.Exception
+       is also fine.
+
+       * expression.cs (Binary.ResolveOperator): Check error result in
+       two places.
+
+       use brtrue/brfalse directly and avoid compares to null.
+
+2002-08-02  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (TypeContainer.Define): Define all nested interfaces here.
+       Fixes bug #28407, added test-155.cs.
+
+2002-08-01  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (Event.EmitDefaultMethod): Make this work with static
+       events.  Fixes #28311, added verify-3.cs.
+
+2002-08-01  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (ForeachHelperMethods): Added `enumerator_type' and
+       `is_disposable' fields.
+       (Foreach.GetEnumeratorFilter): Set `hm.enumerator_type' and
+       `hm.is_disposable' if we're using the collection pattern.
+       (Foreach.EmitCollectionForeach): Use the correct type for the
+       enumerator's local variable, only emit the try/finally block if
+       necessary (fixes #27713).
+
+2002-08-01  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.report118): Renamed to Error118 and made
+       it public static.
+
+       * statement.cs (Throw.Resolve): Check whether the expression is of
+       the correct type (CS0118) and whether the type derives from
+       System.Exception (CS0155).
+       (Catch.Resolve): New method.  Do the type lookup here and check
+       whether it derives from System.Exception (CS0155).
+       (Catch.CatchType, Catch.IsGeneral): New public properties.
+
+       * typemanager.cs (TypeManager.exception_type): Added.
+
+2002-07-31  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Updated About function.
+
+2002-07-31  Martin Baulig  <martin@gnome.org>
+
+       Implemented Control Flow Analysis.
+
+       * codegen.cs (EmitContext.DoFlowAnalysis): New public variable.
+       (EmitContext.CurrentBranching): Added.
+       (EmitContext.StartFlowBranching): Added.
+       (EmitContext.EndFlowBranching): Added.
+       (EmitContext.KillFlowBranching): Added.
+       (EmitContext.IsVariableAssigned): Added.
+       (EmitContext.SetVariableAssigned): Added.
+       (EmitContext.IsParameterAssigned): Added.
+       (EmitContext.SetParameterAssigned): Added.
+       (EmitContext.EmitTopBlock): Added `InternalParameters ip' argument.
+       Added control flow analysis stuff here.
+
+       * expression.cs (Unary.DoResolve): If the operator is Oper.AddressOf,
+       resolve the expression as lvalue.
+       (LocalVariableReference.DoResolve): Check whether the variable has
+       already been assigned.
+       (ParameterReference.DoResolveLValue): Override lvalue resolve to mark
+       the parameter as assigned here.
+       (ParameterReference.DoResolve): Check whether the parameter has already
+       been assigned.
+       (Argument.Resolve): If it's a `ref' or `out' argument, resolve the
+       expression as lvalue.
+
+       * statement.cs (FlowBranching): New class for the flow analysis code.
+       (Goto): Resolve the label in Resolve, not in Emit; added flow analysis.
+       (LabeledStatement.IsDefined): New public property.
+       (LabeledStatement.AddUsageVector): New public method to tell flow
+       analyis that the label may be reached via a forward jump.
+       (GotoCase): Lookup and resolve the label in Resolve, not in Emit; added
+       flow analysis.
+       (VariableInfo.Number): New public field.  This is used by flow analysis
+       to number all locals of a block.
+       (Block.CountVariables): New public property.  This is the number of
+       local variables in this block (including the locals from all parent
+       blocks).
+       (Block.EmitMeta): Number all the variables.
+
+       * statement.cs: Added flow analysis support to all classes.
+
+2002-07-31  Martin Baulig  <martin@gnome.org>
+
+       * driver.cs: Added "--mcs-debug" argument if MCS_DEBUG is defined.
+       To get debugging messages, compile mcs with /define:MCS_DEBUG and
+       then use this argument.
+
+       * report.cs (Report.Debug): Renamed to conditional to "MCS_DEBUG".
+
+       * makefile.gnu (MCS_FLAGS): Include $(MCS_DEFINES), the user may
+       use this to specify /define options.
+
+2002-07-29  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Fixed): Moved all code that does variable lookups
+       and resolvings from Emit to Resolve.
+
+       * statement.cs (For): Moved all code that does variable lookups
+       and resolvings from Emit to Resolve.
+
+       * statement.cs (Using): Moved all code that does variable lookups
+       and resolvings from Emit to Resolve.
+
+2002-07-29  Martin Baulig  <martin@gnome.org>
+
+       * attribute.cs (Attribute.Resolve): Explicitly catch a
+       System.NullReferenceException when creating the
+       CustromAttributeBuilder and report a different warning message.
+
+2002-07-29  Martin Baulig  <martin@gnome.org>
+
+       * support.cs (ParameterData.ParameterName): Added method to
+       get the name of a parameter.
+
+       * typemanager.cs (TypeManager.IsValueType): New public method.
+
+2002-07-29  Martin Baulig  <martin@gnome.org>
+
+       * parameter.cs (Parameter.Modifier): Added `ISBYREF = 8'.  This
+       is a flag which specifies that it's either ref or out.
+       (Parameter.GetParameterInfo (DeclSpace, int, out bool)): Changed
+       the out parameter to `out Parameter.Modifier mod', also set the
+       Parameter.Modifier.ISBYREF flag on it if it's either ref or out.
+
+       * support.cs (InternalParameters.ParameterModifier): Distinguish
+       between Parameter.Modifier.OUT and Parameter.Modifier.REF, set the
+       Parameter.Modifier.ISBYREF flag if it's either ref or out.
+
+       * expression.cs (Argument.GetParameterModifier): Distinguish
+       between Parameter.Modifier.OUT and Parameter.Modifier.REF, set the
+       Parameter.Modifier.ISBYREF flag if it's either ref or out.
+
+2002-07-29  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (ParameterReference.ParameterReference): Added
+       `Location loc' argument to the constructor.
+
+       * cs-parser.jay: Pass location to ParameterReference.
+
+2002-07-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Try): Initialize the location.
+
+       * cs-parser.jay: pass location to Try.
+
+       * expression.cs (Unary.Reduce): Change the prototype to return
+       whether a constant fold could be performed or not.  The result is
+       returned in an out parameters.  In the case of Indirection and
+       AddressOf, we want to perform the full tests.
+
+2002-07-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Statement.Emit): Flag dead code.
+
+2002-07-27  Andrew Birkett  <andy@nobugs.org>
+
+       * expression.cs (Unary.Reduce): Handle AddressOf and Indirection.
+
+2002-07-27  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (MethodData.Define): Put back call to
+       TypeManager.AddMethod(), accidentally commented this out.
+
+       * report.cs (Debug): New public method to print debugging information,
+       this is `[Conditional ("DEBUG")]'.
+
+2002-07-26  Martin Baulig  <martin@gnome.org>
+
+       * cs-parser.jay (CSharpParser): Added `Stack switch_stack'.
+       (switch_statement): Push the current_block to the switch_stack and
+       pop it again when we're done with the switch.
+       (switch_section): The new block is a child of the current_block.
+       Fixes bug #24007, added test-152.cs.
+
+2002-07-27  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Invocation.EmitArguments): When calling a varargs
+       function with only its fixed arguments, we need to pass an empty
+       array.
+
+2002-07-27  Martin Baulig  <martin@gnome.org>
+
+       Mono 0.13 has been released.
+
+2002-07-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Rename --resource to --linkres, because that is what
+       we do currently, we dont support --resource yet.
+
+       * cs-tokenizer.cs: Fix test for reporting endif mismatches.
+
+2002-07-25  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (MethodData): New public class.  This is a `method builder'
+       class for a method or one accessor of a Property/Indexer/Event.
+       (MethodData.GetMethodFlags): Moved here from MemberBase.
+       (MethodData.ApplyAttributes): Likewise.
+       (MethodData.ApplyObsoleteAttribute): Likewise.
+       (MethodData.ApplyConditionalAttribute): Likewise.
+       (MethodData.ApplyDllImportAttribute): Likewise.
+       (MethodData.CheckAbstractAndExternal): Likewise.
+       (MethodData.Define): Formerly knows as MemberBase.DefineMethod().
+       (MethodData.Emit): Formerly known as Method.Emit().
+       (MemberBase): Moved everything which was specific to a single
+       accessor/method to MethodData.
+       (Method): Create a new MethodData and call Define() and Emit() on it.
+       (Property, Indexer, Event): Create a new MethodData objects for each
+       accessor and call Define() and Emit() on them.
+
+2002-07-25  Martin Baulig  <martin@gnome.org>
+
+       Made MethodCore derive from MemberBase to reuse the code from there.
+       MemberBase now also checks for attributes.
+
+       * class.cs (MethodCore): Derive from MemberBase, not MemberCore.
+       (MemberBase.GetMethodFlags): Moved here from class Method and marked
+       as virtual.
+       (MemberBase.DefineAccessor): Renamed to DefineMethod(), added
+       `CallingConventions cc' and `Attributes opt_attrs' arguments.
+       (MemberBase.ApplyAttributes): New virtual method; applies the
+       attributes to a method or accessor.
+       (MemberBase.ApplyObsoleteAttribute): New protected virtual method.
+       (MemberBase.ApplyConditionalAttribute): Likewise.
+       (MemberBase.ApplyDllImportAttribute): Likewise.
+       (MemberBase.CheckAbstractAndExternal): Likewise.
+       (MethodCore.ParameterTypes): This is now a property instead of a
+       method, it's initialized from DoDefineParameters().
+       (MethodCore.ParameterInfo): Removed the set accessor.
+       (MethodCore.DoDefineParameters): New protected virtual method to
+       initialize ParameterTypes and ParameterInfo.
+       (Method.GetReturnType): We can now simply return the MemberType.
+       (Method.GetMethodFlags): Override the MemberBase version and add
+       the conditional flags.
+       (Method.CheckBase): Moved some code from Define() here, call
+       DoDefineParameters() here.
+       (Method.Define): Use DoDefine() and DefineMethod() from MemberBase
+       here to avoid some larger code duplication.
+       (Property.Emit, Indexer.Emit): Call CheckAbstractAndExternal() to
+       ensure that abstract and external accessors don't declare a body.
+
+       * attribute.cs (Attribute.GetValidPieces): Make this actually work:
+       `System.Attribute.GetCustomAttributes (attr.Type)' does a recursive
+       lookup in the attribute's parent classes, so we need to abort as soon
+       as we found the first match.
+       (Attribute.Obsolete_GetObsoleteMessage): Return the empty string if
+       the attribute has no arguments.
+
+       * typemanager.cs (TypeManager.AddMethod): Now takes a MemberBase instead
+       of a Method.
+
+2002-07-24  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * cs-parser.jay: reverted previous patch.
+
+2002-07-24  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * cs-parser.jay: fixed bug #22119.
+
+2002-07-24  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * attribute.cs: fixed compilation. The error was:
+       "attribute.cs(571,17): error CS0177: The out parameter 'is_error' must 
+       be assigned to before control leaves the current method."
+       [FIXME:  Filed as bug #28186: MCS must report this error.]
+
+2002-07-25  Martin Baulig  <martin@gnome.org>
+
+       * attribute.cs (Attribute.Conditional_GetConditionName): New static
+       method to pull the condition name ouf of a Conditional attribute.
+       (Attribute.Obsolete_GetObsoleteMessage): New static method to pull
+       the obsolete message and error flag out of an Obsolete attribute.
+
+       * class.cs (Method.GetMethodFlags): New public method to get the
+       TypeManager.MethodFlags for this method.
+       (Method.ApplyConditionalAttribute, Method.ApplyObsoleteAttribute): New
+       private methods.
+       (Method.Define): Get and apply the Obsolete and Conditional attributes;
+       if we're overriding a virtual function, set the new private variable
+       `parent_method'; call the new TypeManager.AddMethod().
+
+       * typemanager.cs (TypeManager.AddMethod): New static method.  Stores
+       the MethodBuilder and the Method in a PtrHashtable.
+       (TypeManager.builder_to_method): Added for this purpose.
+       (TypeManager.MethodFlags): Added IsObsoleteError.
+       (TypeManager.GetMethodFlags): Added `Location loc' argument.  Lookup
+       Obsolete and Conditional arguments in MethodBuilders.  If we discover
+       an Obsolete attribute, emit an appropriate warning 618 / error 619 with
+       the message from the attribute.
+
+2002-07-24  Martin Baulig  <martin@gnome.org>
+
+       * cs-tokenizer.cs: Eat up trailing whitespaces and one-line comments in
+       preprocessor directives, ensure that the argument to #define/#undef is
+       exactly one identifier and that it's actually an identifier.
+
+       Some weeks ago I did a `#define DEBUG 1' myself and wondered why this
+       did not work ....
+
+2002-07-24  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Foreach.ForeachHelperMethods): Added `Type element_type',
+       initialize it to TypeManager.object_type in the constructor.
+       (Foreach.GetEnumeratorFilter): Set `hm.element_type' to the return type
+       of the `hm.get_current' method if we're using the collection pattern.
+       (Foreach.EmitCollectionForeach): Use `hm.element_type' as the source type
+       for the explicit conversion to make it work when we're using the collection
+       pattern and the `Current' property has a different return type than `object'.
+       Fixes #27713.
+
+2002-07-24  Martin Baulig  <martin@gnome.org>
+
+       * delegate.cs (Delegate.VerifyMethod): Simply return null if the method
+       does not match, but don't report any errors.  This method is called in
+       order for all methods in a MethodGroupExpr until a matching method is
+       found, so we don't want to bail out if the first method doesn't match.
+       (NewDelegate.DoResolve): If none of the methods in the MethodGroupExpr
+       matches, report the 123.  Fixes #28070.
+
+2002-07-24  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (ArrayAccess.EmitStoreOpcode): Moved the
+       TypeManager.TypeToCoreType() to the top of the method so the
+       following equality checks will work.  Fixes #28107.
+
+2002-07-24  Martin Baulig  <martin@gnome.org>
+
+       * cfold.cs (ConstantFold.DoConstantNumericPromotions): "If either
+       operand is of type uint, and the other operand is of type sbyte,
+       short or int, the operands are converted to type long." -
+       Actually do what this comment already told us.  Fixes bug #28106,
+       added test-150.cs.
+
+2002-07-24  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (MethodBase): New abstract class.  This is now a base
+       class for Property, Indexer and Event to avoid some code duplication
+       in their Define() and DefineMethods() methods.
+       (MethodBase.DoDefine, MethodBase.DefineAccessor): Provide virtual
+       generic methods for Define() and DefineMethods().
+       (FieldBase): Derive from MemberBase, not MemberCore.
+       (Property): Derive from MemberBase, not MemberCore.
+       (Property.DefineMethod): Moved all the code from this method to the
+       new MethodBase.DefineAccessor(), just call it with appropriate
+       argumetnts.
+       (Property.Define): Call the new Property.DoDefine(), this does some
+       sanity checks and we don't need to duplicate the code everywhere.
+       (Event): Derive from MemberBase, not MemberCore.
+       (Event.Define): Use the new MethodBase.DefineAccessor() to define the
+       accessors, this will also make them work with interface events.
+       (Indexer): Derive from MemberBase, not MemberCore.
+       (Indexer.DefineMethod): Removed, call MethodBase.DefineAccessor() insstead.
+       (Indexer.Define): Use the new MethodBase functions.
+
+       * interface.cs (InterfaceEvent.InterfaceEvent): Added `Location loc'
+       argument to the constructor.
+       (Interface.FindMembers): Added support for interface events.
+       (Interface.PopluateEvent): Implemented.
+
+       Added test-149.cs for this.  This also fixes bugs #26067 and #24256.
+
+2002-07-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer.AddMethod): Adding methods do not use IsValid,
+       but this is required to check for a method name being the same as
+       the containing class.  
+
+       Handle this now.
+
+2002-07-22  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * interface.cs: initialize variable.
+
+2002-07-23  Martin Baulig  <martin@gnome.org>
+
+       Implemented the IndexerName attribute in interfaces.
+
+       * class.cs (TypeContainer.DefineIndexers): Don't set the indexer
+       name if this is an explicit interface implementation.
+       (Indexer.InterfaceIndexerName): New public variable.  If we're
+       implementing an interface indexer, this is the IndexerName in that
+       interface.  Otherwise, it's the IndexerName.
+       (Indexer.DefineMethod): If we're implementing interface indexer,
+       set InterfaceIndexerName.  Use the new Pending.IsInterfaceIndexer
+       and Pending.ImplementIndexer methods.
+       (Indexer.Define): Also define the PropertyBuilder if we're
+       implementing an interface indexer and this is neither an explicit
+       interface implementation nor do the IndexerName match the one in
+       the interface.
+
+       * pending.cs (TypeAndMethods): Added `MethodInfo [] need_proxy'.
+       If a method is defined here, then we always need to create a proxy
+       for it.  This is used when implementing interface indexers.
+       (Pending.IsInterfaceIndexer): New public method.
+       (Pending.ImplementIndexer): New public method.
+       (Pending.InterfaceMethod): Added `MethodInfo need_proxy' argument.
+       This is used when implementing interface indexers to define a proxy
+       if necessary.
+       (Pending.VerifyPendingMethods): Look in the `need_proxy' array and
+       define a proxy if necessary.
+
+       * interface.cs (Interface.IndexerName): New public variable.
+       (Interface.PopulateIndexer): Set the IndexerName.
+       (Interface.DefineIndexers): New private method.  Populate all the
+       indexers and make sure their IndexerNames match.
+
+       * typemanager.cs (IndexerPropertyName): Added support for interface
+       indexers.
+
+2002-07-22  Martin Baulig  <martin@gnome.org>
+
+       * codegen.cs (EmitContext.HasReturnLabel): New public variable.
+       (EmitContext.EmitTopBlock): Always mark the ReturnLabel and emit a
+       ret if HasReturnLabel.
+       (EmitContext.TryCatchLevel, LoopBeginTryCatchLevel): New public
+       variables.
+
+       * statement.cs (Do.Emit, While.Emit, For.Emit, Foreach.Emit): Save
+       and set the ec.LoopBeginTryCatchLevel.
+       (Try.Emit): Increment the ec.TryCatchLevel while emitting the block.
+       (Continue.Emit): If the ec.LoopBeginTryCatchLevel is smaller than
+       the current ec.TryCatchLevel, the branch goes out of an exception
+       block.  In this case, we need to use Leave and not Br.
+
+2002-07-22  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Try.Emit): Emit an explicit ret after the end of the
+       block unless the block does not always return or it is contained in
+       another try { ... } catch { ... } block.  Fixes bug #26506.
+       Added verify-1.cs to the test suite.
+
+2002-07-22  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Switch.TableSwitchEmit): If we don't have a default,
+       then we do not always return.  Fixes bug #24985.
+
+2002-07-22  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Invocation.OverloadedResolve): Do the BetterFunction()
+       lookup on a per-class level; ie. walk up the class hierarchy until we
+       found at least one applicable method, then choose the best among them.
+       Fixes bug #24463 and test-29.cs.
+
+2002-07-22  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.ArrayContainsMethod): Don't check the
+       return types of the methods.  The return type is not part of the
+       signature and we must not check it to make the `new' modifier work.
+       Fixes bug #27999, also added test-147.cs.
+       (TypeManager.TypeToCoreType): Added TypeManager.type_type.
+
+       * expression.cs (Invocation.DoResolve): Call TypeManager.TypeToCoreType()
+       on the method's return type.
+
+2002-07-21  Martin Baulig  <martin@gnome.org>
+
+       * assign.cs: Make this work if the rightmost source is a constant and
+       we need to do an implicit type conversion.  Also adding a few more tests
+       to test-38.cs which should have caught this.
+
+       * makefile.gnu: Disable debugging, there's already the mcs-mono2.exe
+       target in the makefile for this.  The makefile.gnu is primarily intended
+       for end-users who don't want to debug the compiler.
+
+2002-07-21  Martin Baulig  <martin@gnome.org>
+
+       * assign.cs: Improved the Assign class so it can now handle embedded
+       assignments (X = Y = Z = something).  As a side-effect this'll now also
+       consume less local variables.  test-38.cs now passes with MCS, added
+       a few new test cases to that test.
+
+2002-07-20  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Binary.EmitBranchable): Emit correct unsigned branch
+       instructions.  Fixes bug #27977, also added test-146.cs.
+
+2002-07-19  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * cs-tokenizer.cs: fixed getHex ().
+
+2002-07-19  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Invocation.EmitParams): Use TypeManager.LookupType(),
+       not Type.GetType() to lookup the array type.  This is needed when
+       we're constructing an array of a user-defined type.
+       (ArrayAccess.EmitDynamicInitializers): Only emit the Ldelema for
+       single-dimensional arrays, but also for single-dimensial arrays of
+       type decimal.
+
+2002-07-19  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (New.DoEmit): Create a new LocalTemporary each time
+       this function is called, it's not allowed to share LocalBuilders
+       among ILGenerators.
+
+2002-07-19  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Argument.Resolve): Report an error 118 when trying
+       to pass a type as argument.
+
+2002-07-18  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.ImplicitNumericConversion): Don't emit a
+       Conv_R_Un for the signed `long' type.
+
+2002-07-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (MemberAccess.DoResolve): Do not reuse the field
+       `expr' for the temporary result, as that will fail if we do
+       multiple resolves on the same expression.
+
+2002-07-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (SimpleNameResolve): Use ec.DeclSpace instead of
+       ec.TypeContainer for looking up aliases. 
+
+       * class.cs (TypeContainer): Remove LookupAlias from here.
+
+       * decl.cs (DeclSpace); Move here.
+
+2002-07-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (FindMembers): Only call filter if the constructor
+       bulider is not null.
+
+       Also handle delegates in `NestedTypes' now.  Now we will perform
+       type lookups using the standard resolution process.  This also
+       fixes a bug.
+
+       * decl.cs (DeclSpace.ResolveType): New type resolution routine.
+       This uses Expressions (the limited kind that can be parsed by the
+       tree) instead of strings.
+
+       * expression.cs (ComposedCast.ToString): Implement, used to flag
+       errors since now we have to render expressions.
+
+       (ArrayCreation): Kill FormElementType.  Use ComposedCasts in
+       FormArrayType. 
+
+       * ecore.cs (SimpleName.ToString): ditto.
+
+       * cs-parser.jay: Instead of using strings to assemble types, use
+       Expressions to assemble the type (using SimpleName, ComposedCast,
+       MemberAccess).  This should fix the type lookups in declarations,
+       because we were using a different code path for this.
+
+       * statement.cs (Block.Resolve): Continue processing statements
+       even when there is an error.
+
+2002-07-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Event.Define): Also remove the `remove' method from
+       the list of pending items.
+
+       * expression.cs (ParameterReference): Use ldarg.N (0..3) to
+       generate more compact code. 
+
+2002-07-17  Martin Baulig  <martin@gnome.org>
+
+       * const.cs (Const.LookupConstantValue): Add support for constant
+       `unchecked' and `checked' expressions.
+       Also adding test case test-140.cs for this.
+
+2002-07-17  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Foreach.GetEnumeratorFilter): When compiling corlib,
+       check whether mi.ReturnType implements the IEnumerator interface; the
+       `==' and the IsAssignableFrom() will fail in this situation.
+
+2002-07-16  Ravi Pratap  <ravi@ximian.com>
+
+       * ecore.cs (SimpleName.SimpleNameResolve) : Apply Gonzalo's fix 
+       here too.
+
+2002-07-16  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * expression.cs: fixed bug #27811.
+
+2002-07-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ParameterReference.AddressOf): Patch from Paolo
+       Molaro: when we are a ref, the value already contains a pointer
+       value, do not take the address of it.
+
+2002-07-14 Rafael Teixeira <rafaelteixeirabr@hotmail.com>
+       * removed mb-parser.jay and mb-tokenizer.cs
+
+Sat Jul 13 19:38:03 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * expression.cs: check against the building corlib void type.
+
+Sat Jul 13 19:35:58 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * ecore.cs: fix for valuetype static readonly fields: when 
+       initializing them, we need their address, not the address of a copy.
+
+Sat Jul 13 17:32:53 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * typemanager.cs: register also enum_type in corlib.
+
+Sat Jul 13 15:59:47 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * class.cs: allow calling this (but not base) initializers in structs.
+
+Sat Jul 13 15:12:06 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * ecore.cs: make sure we compare against the building base types
+       in GetTypeSize ().
+
+Sat Jul 13 15:10:32 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * typemanager.cs: fix TypeToCoreType() to handle void and object
+       (corlib gets no more typerefs after this change).
+
+2002-07-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ArrayCreation.EmitArrayArguments): use
+       Conv.Ovf.U4 for unsigned and Conv.Ovf.I4 for signed.
+
+       (ArrayAccess.LoadArrayAndArguments): Use Conv_Ovf_I and
+       Conv_Ovf_I_Un for the array arguments.  Even if C# allows longs as
+       array indexes, the runtime actually forbids them.
+
+       * ecore.cs (ExpressionToArrayArgument): Move the conversion code
+       for array arguments here.
+
+       * expression.cs (EmitLoadOpcode): System.Char is a U2, use that
+       instead of the default for ValueTypes.
+
+       (New.DoEmit): Use IsValueType instead of
+       IsSubclassOf (value_type)
+       (New.DoResolve): ditto.
+       (Invocation.EmitCall): ditto.
+
+       * assign.cs (Assign): ditto.
+
+       * statement.cs (Unsafe): Ok, so I got the semantics wrong.
+       Statements *are* currently doing part of their resolution during
+       Emit.  
+
+       Expressions do always resolve during resolve, but statements are
+       only required to propagate resolution to their children.
+
+2002-07-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs (CSCParseOption): Finish the /r: and /lib: support.
+
+       (LoadAssembly): Do not add the dll if it is already specified
+
+       (MainDriver): Add the System directory to the link path at the end,
+       after all the other -L arguments. 
+
+       * expression.cs (ArrayAccess.EmitLoadOpcode): I was using the
+       wrong opcode for loading bytes and bools (ldelem.i1 instead of
+       ldelem.u1) and using the opposite for sbytes.
+
+       This fixes Digger, and we can finally run it.
+
+       * driver.cs (UnixParseOption): Move the option parsing here.  
+       (CSCParseOption): Implement CSC-like parsing of options.
+
+       We now support both modes of operation, the old Unix way, and the
+       new CSC-like way.  This should help those who wanted to make cross
+       platform makefiles.
+
+       The only thing broken is that /r:, /reference: and /lib: are not
+       implemented, because I want to make those have the same semantics
+       as the CSC compiler has, and kill once and for all the confussion
+       around this.   Will be doing this tomorrow.
+
+       * statement.cs (Unsafe.Resolve): The state is checked during
+       resolve, not emit, so we have to set the flags for IsUnsfe here.
+
+2002-07-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (MemberAccess.ResolveMemberAccess): Since we can
+       not catch the Error_ObjectRefRequired in SimpleName (as it is
+       possible to have a class/instance variable name that later gets
+       deambiguated), we have to check this here.      
+
+2002-07-10  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer.GetFieldFromEvent): Move away from here,
+       make static and put into Expression.
+
+       (Event.Define): Register the private field of the event with the 
+       TypeManager so that GetFieldFromEvent can get at it.
+
+       (TypeManager.RegisterPrivateFieldOfEvent): Implement to
+       keep track of the private field associated with an event which
+       has no accessors.
+
+       (TypeManager.GetPrivateFieldOfEvent): Implement to get at the
+       private field.
+
+       * ecore.cs (GetFieldFromEvent): RE-write to use the above methods.
+
+2002-07-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Binary.EmitBranchable): this routine emits the
+       Binary expression in a branchable context.  This basically means:
+       we need to branch somewhere, not just get the value on the stack.
+
+       This works together with Statement.EmitBoolExpression.
+
+       * statement.cs (Statement.EmitBoolExpression): Use
+       EmitBranchable. 
+
+2002-07-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (For): Reduce the number of jumps in loops.
+
+       (For): Implement loop inversion for the For statement.
+
+       (Break): We can be breaking out of a Try/Catch controlled section
+       (foreach might have an implicit try/catch clause), so we need to
+       use Leave instead of Br.
+
+       * ecore.cs (FieldExpr.AddressOf): Fix for test-139 (augmented
+       now).  If the instace expression supports IMemoryLocation, we use
+       the AddressOf method from the IMemoryLocation to extract the
+       address instead of emitting the instance.
+
+       This showed up with `This', as we were emitting the instance
+       always (Emit) instead of the Address of This.  Particularly
+       interesting when This is a value type, as we dont want the Emit
+       effect (which was to load the object).
+
+2002-07-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs: Pass the entry point to the DefinePInvokeMethod
+
+       * statement.cs (Checked): Set the CheckedState during the resolve
+       process too, as the ConvCast operations track the checked state on
+       the resolve process, and not emit.
+
+       * cs-parser.jay (namespace_member_declaration): Flag that we have
+       found a declaration when we do.  This is used to flag error 1529
+
+       * driver.cs: Report ok when we display the help only.
+
+2002-07-06  Andrew Birkett  <adb@tardis.ed.ac.uk>
+
+       * cs-tokenizer.cs (xtoken): Improve handling of string literals.
+
+2002-07-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs (define): We also have to track locally the
+       defines.  AllDefines is just used for the Conditional Attribute,
+       but we also need the local defines for the current source code. 
+
+2002-07-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (While, For, Do): These loops can exit through a
+       Break statement, use this information to tell whether the
+       statement is the last piece of code.
+
+       (Break): Flag that we break.
+
+       * codegen.cs (EmitContexts): New `Breaks' state variable.
+
+2002-07-03  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (TypeContainer.MethodModifiersValid): Allow override
+       modifiers in method declarations in structs.  Otherwise, you won't
+       be able to override things like Object.Equals().
+
+2002-07-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Method, Property, Indexer): Do not allow the public
+       modifier to be used in explicit interface implementations.
+
+       (TypeContainer.MethodModifiersValid): Catch virtual, abstract and
+       override modifiers in method declarations in structs
+
+2002-07-02   Andrew Birkett <adb@tardis.ed.ac.uk>
+
+       * cs-tokenizer.cs (adjust_int, adjust_real): Do not abort on
+       integer or real overflow, report an error
+
+2002-07-02  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.InitCoreTypes): When compiling
+       corlib, dynamically call AssemblyBuilder.SetCorlibTypeBuilders()
+       to tell the runtime about our newly created System.Object and
+       System.ValueType types.
+
+2002-07-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (This): Use Stobj/Ldobj when we are a member of a
+       struct instead of Ldarg/Starg.
+
+2002-07-02  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Indirection.Indirection): Call
+       TypeManager.TypeToCoreType() on `expr.Type.GetElementType ()'.
+
+2002-07-02  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (ArrayAccess.EmitStoreOpcode): If the type is a
+       ValueType, call TypeManager.TypeToCoreType() on it.
+       (Invocations.EmitParams): Call TypeManager.TypeToCoreType() on
+       the OpCodes.Newarr argument.
+
+2002-07-02  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Invocation.EmitCall): When compiling corlib,
+       replace all calls to the system's System.Array type to calls to
+       the newly created one.
+
+       * typemanager.cs (TypeManager.InitCodeHelpers): Added a few more
+       System.Array methods.
+       (TypeManager.InitCoreTypes): When compiling corlib, get the methods
+       from the system's System.Array type which must be replaced.
+
+Tue Jul 2 19:05:05 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * typemanager.cs: load unverifiable_code_ctor so we can build
+       corlib using the correct type. Avoid using GetTypeCode() with
+       TypeBuilders.
+       * rootcontext.cs: uses TypeManager.unverifiable_code_ctor and
+       TypeManager.object_type to allow building corlib.
+
+Tue Jul 2 19:03:19 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * ecore.cs: handle System.Enum separately in LoadFromPtr().
+
+2002-07-01  Martin Baulig  <martin@gnome.org>
+
+       * class.cs: Make the last change actually work, we need to check
+       whether `ifaces != null' to avoid a crash.
+
+Mon Jul 1 16:15:03 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * class.cs: when we build structs without fields that implement
+       interfaces, we need to add the interfaces separately, since there is
+       no API to both set the size and add the interfaces at type creation
+       time.
+
+Mon Jul 1 14:50:47 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * expression.cs: the dimension arguments to the array constructors
+       need to be converted if they are a long.
+
+Mon Jul 1 12:26:12 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * class.cs: don't emit ldarg.0 if there is no parent constructor
+       (fixes showstopper for corlib).
+
+2002-06-29  Martin Baulig  <martin@gnome.org>
+
+       MCS now compiles corlib on GNU/Linux :-)
+
+       * attribute.cs (Attribute.ApplyAttributes): Treat Accessors like Method,
+       ie. check for MethodImplOptions.InternalCall.
+
+       * class.cs (TypeContainer.DefineType): When compiling corlib, both parent
+       and TypeManager.attribute_type are null, so we must explicitly check
+       whether parent is not null to find out whether it's an attribute type.
+       (Property.Emit): Always call Attribute.ApplyAttributes() on the GetBuilder
+       and SetBuilder, not only if the property is neither abstract nor external.
+       This is necessary to set the MethodImplOptions on the accessor methods.
+       (Indexer.Emit): Call Attribute.ApplyAttributes() on the GetBuilder and
+       SetBuilder, see Property.Emit().
+
+       * rootcontext.cs (RootContext.PopulateTypes): When compiling corlib, don't
+       populate "System.Object", "System.ValueType" and "System.Attribute" since
+       they've already been populated from BootCorlib_PopulateCoreTypes().
+
+2002-06-29  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.ImplicitReferenceConversionExists): If expr
+       is the NullLiteral, we also need to make sure that target_type is not
+       an enum type.   
+
+2002-06-29  Martin Baulig  <martin@gnome.org>
+
+       * rootcontext.cs (RootContext.ResolveCore): We must initialize
+       `TypeManager.multicast_delegate_type' and `TypeManager.delegate_type'
+       before calling BootstrapCorlib_ResolveDelegate ().
+
+2002-06-27  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * statement.cs: fixed build-breaker. All tests passed ok.
+
+2002-06-27  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.VerifyUnManaged): Added explicit check
+       for System.Decimal when compiling corlib.
+
+2002-06-27  Martin Baulig  <martin@gnome.org>
+
+       * statement.cs (Switch.TableSwitchEmit): Make this work with empty
+       switch blocks which contain nothing but a default clause.
+
+2002-06-26  Andrew  <adb@tardis.ed.ac.uk>
+
+       * ../errors/cs1501-3.cs: Added new test for struct ctr typechecks.
+
+2002-06-27  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (PropertyExpr.PropertyExpr): Call
+       TypeManager.TypeToCoreType() on the `pi.PropertyType'.
+
+       * typemanager.cs (TypeManager.TypeToCoreType): Return if the type
+       is already a TypeBuilder.
+
+2002-06-27  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.ImplicitReferenceConversionExists): Use
+       `target_type == TypeManager.array_type', not IsAssignableFrom() in
+       the "from an array-type to System.Array" case.  This makes it work
+       when compiling corlib.
+
+2002-06-27  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.SimpleNameResolve): If the expression is a
+       non-static PropertyExpr, set its InstanceExpression.  This makes
+       the `ICollection.Count' property work in System/Array.cs.
+
+2002-06-25  Andrew Birkett  <adb@tardis.ed.ac.uk>
+
+       * driver.cs: Made error handling more consistent.  Errors now
+       tracked by Report class, so many methods which used to return int
+       now return void.  Main() now prints success/failure and 
+       errors/warnings message.
+
+       Renamed '--probe' compiler argument to '--expect-error'.  Removed
+       the magic number return values (123 and 124).  Now, if the
+       expected error occurs, the compiler exits with success (exit value
+       0).  If the compilation completes without seeing that particular
+       error, the compiler exits with failure (exit value 1).  The
+       makefile in mcs/errors has been changed to handle the new behaviour.
+
+       * report.cs: Made 'expected error' number a property and renamed
+       it from 'Probe' to 'ExpectedError'.
+
+       * genericparser.cs: Removed error handling support, since it is
+       now all done by Report class.
+
+       * cs-parser.jay, mb-parser.jay: Errors are tracked by Report
+       class, so parse() no longer returns an int.
+
+       * namespace.cs: Use Report.Error instead of GenericParser.error
+
+2002-06-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer.AddMethod, TypeContainer.AddIndexer,
+       TypeContainer.AddOperator): At the front of the list put the
+       explicit implementations, so they get resolved/defined first. 
+
+2002-06-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer.VerifyImplements): Verifies that a given
+       interface type is implemented by this TypeContainer.  Used during
+       explicit interface implementation.
+
+       (Property.Define, Indexer.Define, Method.Define): Validate that
+       the given interface in the explicit implementation is one of the
+       base classes for the containing type.
+
+       Also if we are explicitly implementing an interface, but there is
+       no match in the pending implementation table, report an error.
+
+       (Property.Define): Only define the property if we are
+       not explicitly implementing a property from an interface.  Use the
+       correct name also for those properties (the same CSC uses,
+       although that is really not needed).
+
+       (Property.Emit): Do not emit attributes for explicitly implemented
+       properties, as there is no TypeBuilder.
+
+       (Indexer.Emit): ditto.
+
+       Hiding then means that we do not really *implement* a pending
+       implementation, which makes code fail.
+
+2002-06-22  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.Constantify): Call TypeManager.TypeToCoreType() on
+       the return value of Object.GetType().  [FIXME: we need to do this whenever
+       we get a type back from the reflection library].
+
+Fri Jun 21 13:37:57 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * typemanager.cs: make ExpandInterfaces() slip duplicated interfaces.
+
+2002-06-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs: Return null if we can not look up the type.
+
+       * class.cs (TypeContainer.GetClassBases): Use ExpandInterfaces on
+       the interface types found.
+
+       * interface.cs (Interface.GetInterfaceBases): Use ExpandInterfaces on the
+       interface types found.
+
+       * typemanager.cs (GetInterfaces): Make this routine returns alll
+       the interfaces and work around the lame differences between
+       System.Type and System.Reflection.Emit.TypeBuilder in the results
+       result for GetInterfaces.
+
+       (ExpandInterfaces): Given an array of interface types, expand and
+       eliminate repeated ocurrences of an interface.  This expands in
+       context like: IA; IB : IA; IC : IA, IB; the interface "IC" to
+       be IA, IB, IC.
+
+2002-06-21  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.EnumToUnderlying): It's now safe to call this function
+       on System.Enum.
+
+2002-06-21  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (TypeManager.TypeToCoreType): New function.  When compiling corlib
+       and called with one of the core types, return the corresponding typebuilder for
+       that type.
+
+       * expression.cs (ArrayAccess.DoResolve): Call TypeManager.TypeToCoreType() on the
+       element type.
+
+2002-06-21  Martin Baulig  <martin@gnome.org>
+
+       * ecore.cs (Expression.ExplicitReferenceConversionExists): Use
+       `target_type.IsArray' instead of `target_type.IsSubclassOf (TypeManager.array_type)'.
+       (Expression.ConvertReferenceExplicit): Likewise.
+
+       * expression.cs (ElementAccess.DoResolve): Likewise.
+       (ElementAccess.DoResolveLValue): Likewise.
+
+2002-06-10  Martin Baulig  <martin@gnome.org>
+
+       * interface.cs (Interface.PopulateIndexer): When creating the setter, we need to
+       add the "value" parameter to the parameter list.
+
+       * statement.cs (Fixed.Emit): Pass the return value of the child block's Emit()
+       to our caller.
+
+2002-06-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ArrayCreation.ExpressionToArrayArgument): Convert
+       the argument to an int, uint, long or ulong, per the spec.  Also
+       catch negative constants in array creation.
+
+Thu Jun 20 17:56:48 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * class.cs: do not allow the same interface to appear twice in
+       the definition list.
+
+Wed Jun 19 22:33:37 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * ecore.cs: don't use ldlen with System.Array.
+
+Wed Jun 19 20:57:40 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * ecore.cs: stobj requires a type argument. Handle indirect stores on enums.
+
+Wed Jun 19 20:17:59 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * modifiers.cs: produce correct field attributes for protected
+       internal. Easy fix so miguel can work on ther harder stuff:-)
+
+2002-06-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * pending.cs: New file.  Move the code from class.cs here.
+       Support clearning the pending flag for all methods (when not doing
+       explicit interface implementation).
+
+Tue Jun 18 10:36:22 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * rootcontext.cs: added a couple more types needed to bootstrap.
+
+2002-06-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (GetConstructor): Use DeclaredOnly to look the
+       constructor in the type, instead of any constructor in the type
+       hierarchy.  Thanks to Paolo for finding this bug (it showed up as
+       a bug in the Mono runtime when applying the params attribute). 
+
+2002-06-16  Rafael Teixeira  <rafaelteixeirabr@hotmail.com>
+       * changed namespace.cs to use "GenericParser.error(...)" instead of "CSharpParser.error(...)"
+
+2002-06-14  Rachel Hestilow  <hestilow@ximian.com>
+
+       * expression.cs (Unary.ResolveOperator): Use TypeManager
+       to resolve the type.
+
+2002-06-13  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (enum_member_declaration): Pass in the attributes
+       attached.
+
+       * enum.cs (AddEnumMember): Add support to store the attributes associated 
+       with each member too.
+
+       * attribute.cs (CheckAttribute, ApplyAttributes): Update to handle
+       field builders too - this takes care of the enum member case.
+
+2002-06-10  Rachel Hestilow  <hestilow@ximian.com>
+
+       * typemanager.cs (TypeManager.VerifyUnManaged): Allow
+       address-of operator on both value types and pointers.
+
+2002-06-10  Martin Baulig  <martin@gnome.org>
+
+       * interface.cs (Interface.PopulateIndexer): Add the indexer's
+       PropertyBuilder to the `property_builders' list.
+
+       * expression.cs (Indexers.GetIndexersForTypeOrInterface): New private method.
+       (Indexers.GetIndexersForType): Call GetIndexersForTypeOrInterface() on the
+       `lookup_type' and all its interfaces.  Unfortunately, Type.FindMembers() won't
+       find any indexers which are inherited from an interface.
+
+2002-06-09  Martin Baulig  <martin@gnome.org>
+
+       * const.cs (Const.LookupConstantValue): Convert `Expr' to a literal of
+       the same type as the constant if necessary.  There's also a test-130.cs
+       for this.
+
+       * enum.cs (Enum.ChangeEnumType): Moved to typemanager.cs and made public.
+
+       * typemanager.cs (TypeManager.ChangeType): Previously known as
+       Enum.ChangeEnumType().
+
+2002-06-09  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Cast.TryReduce): Added support for consts.
+
+2002-06-08  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Accessor): Hold attributes information so we can pass
+       it along.
+
+       * cs-parser.jay (get_accessor_declaration, set_accessor_declaration):
+       Modify to pass in attributes attached to the methods.
+
+       (add_accessor_declaration, remove_accessor_declaration): Ditto.
+
+       * attribute.cs (ApplyAttributes, CheckAttribute): Update accordingly
+       to handle the Accessor kind :-)
+
+       * class.cs (Property.Emit, Event.Emit): Apply attributes to the accessors
+
+2002-06-08  Martin Baulig  <martin@gnome.org>
+
+       * expression.cs (Unary.TryReduceNegative): Added support for
+       ULongConstants.
+
+2002-06-08  Martin Baulig  <martin@gnome.org>
+
+       * enum.cs (Enum.LookupEnumValue): Don't report an error if the
+       name can't be found in the `defined_names' - the caller will do a
+       MemberLookup in this case and thus find methods in System.Enum
+       such as Enum.IsDefined().
+
+2002-06-08  Martin Baulig  <martin@gnome.org>
+
+       * enum.cs (Enum.ChangeEnumType): This is a custom version of
+       Convert.ChangeType() which works with TypeBuilder created types.
+       (Enum.LookupEnumValue, Enum.Define): Use it here.
+
+       * class.cs (TypeContainer.RegisterRequiredImplementations): Added
+       `TypeBuilder.BaseType != null' check.
+       (TypeContainer.FindMembers): Only lookup parent members if we
+       actually have a parent.
+       (Method.EmitDestructor): Added `ec.ContainerType.BaseType != null' check.
+       (ConstructorInitializer.Resolve): Likewise.
+
+       * interface.cs (Interface.FindMembers): Added
+       `TypeBuilder.BaseType != null' check.
+
+       * rootcontext.cs (RootContext.ResolveCore): Added
+       "System.Runtime.CompilerServices.IndexerNameAttribute" to
+       classes_second_stage.
+
+       * typemanager.cs (TypeManager.InitCoreTypes): Don't initialize
+       debug_type and trace_type when compiling with --nostdlib.       
+
+2002-06-07  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (TypeContainer): Added `have_nonstatic_fields' field.
+       (AddField): Set it to true when adding a non-static field.
+       (DefineType): Use `have_nonstatic_fields' to find out whether we
+       have non-static fields, not `Fields != null'.
+
+2002-06-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (SimpleNameResolve): Removed simple bug (we were
+       dereferencing a null on the static-field code path)
+
+2002-05-30  Martin Baulig  <martin@gnome.org>
+
+       * codegen.cs (InitMonoSymbolWriter): Added `string[] args' argument
+       to take command line arguments.  Use reflection to call the new
+       custom `Initialize' function on the symbol writer and pass it the
+       command line arguments.
+
+       * driver.cs (--debug-args): New command line argument to pass command
+       line arguments to the symbol writer.
+
+2002-05-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs (DoResolve): Forgot to do the implicit conversion to
+       the target type for indexers and properties.  Thanks to Joe for
+       catching this.
+
+2002-05-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (MethodFlags): returns the method flags
+       (Obsolete/ShouldIgnore) that control warning emission and whether
+       the invocation should be made, or ignored. 
+
+       * expression.cs (Invocation.Emit): Remove previous hack, we should
+       not do this on matching a base type, we should do this based on an attribute
+
+       Only emit calls to System.Diagnostics.Debug and
+       System.Diagnostics.Trace if the TRACE and DEBUG defines are passed
+       on the command line.
+
+       * rootcontext.cs: Global settings for tracing and debugging.
+
+       * cs-tokenizer.cs (define): New utility function to track
+       defines.   Set the global settings for TRACE and DEBUG if found.
+
+2002-05-25  Ravi Pratap  <ravi@ximian.com>
+
+       * interface.cs (Populate*): Pass in the TypeContainer as well as
+       the DeclSpace as parameters so that we can create EmitContexts and
+       then use that to apply attributes etc.
+
+       (PopulateMethod, PopulateEvent, PopulateProperty)
+       (PopulateIndexer): Apply attributes everywhere.
+
+       * attribute.cs (CheckAttribute): Include InterfaceMethod, InterfaceEvent
+       etc.
+
+       (ApplyAttributes): Update accordingly.
+
+       We now apply interface attributes for all members too.
+
+2002-05-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Indexer.Define); Correctly check if we are explicit
+       implementation (instead of checking the Name for a ".", we
+       directly look up if the InterfaceType was specified).
+
+       Delay the creation of the PropertyBuilder.
+
+       Only create the PropertyBuilder if we are not an explicit
+       interface implementation.   This means that explicit interface
+       implementation members do not participate in regular function
+       lookups, and hence fixes another major ambiguity problem in
+       overload resolution (that was the visible effect).
+
+       (DefineMethod): Return whether we are doing an interface
+       implementation. 
+
+       * typemanager.cs: Temporary hack until we get attributes in
+       interfaces (Ravi is working on that) and we get IndexerName
+       support in interfaces.
+
+       * interface.cs: Register the indexers as properties.
+
+       * attribute.cs (Attribute.Resolve): Catch the error, and emit a
+       warning, I have verified that this is a bug in the .NET runtime
+       (JavaScript suffers of the same problem).
+
+       * typemanager.cs (MemberLookup): When looking up members for
+       interfaces, the parent of an interface is the implicit
+       System.Object (so we succeed in searches of Object methods in an
+       interface method invocation.  Example:  IEnumerable x;  x.ToString
+       ()) 
+
+2002-05-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Event): Events should also register if they do
+       implement the methods that an interface requires.
+
+       * typemanager.cs (MemberLookup); use the new GetInterfaces
+       method. 
+
+       (GetInterfaces): The code used to lookup interfaces for a type is
+       used in more than one place, factor it here. 
+
+       * driver.cs: Track the errors at the bottom of the file, we kept
+       on going.
+
+       * delegate.cs (NewDelegate.Emit): We have to emit a null as the
+       instance if the method we are calling is static!
+
+2002-05-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs (ApplyAttributes): Make this function filter out
+       the IndexerName attribute (as that attribute in reality is never
+       applied) and return the string constant for the IndexerName
+       attribute. 
+
+       * class.cs (TypeContainer.Emit): Validate that all the indexers
+       have the same IndexerName attribute, and if so, set the
+       DefaultName attribute on the class. 
+
+       * typemanager.cs: The return value might contain other stuff (not
+       only methods).  For instance, consider a method with an "Item"
+       property and an Item method.
+
+       * class.cs: If there is a problem with the parameter types,
+       return. 
+
+2002-05-24  Ravi Pratap  <ravi@ximian.com>
+
+       * ecore.cs (ImplicitConversionExists): Wrapper function which also
+       looks at user defined conversion after making a call to 
+       StandardConversionExists - we need this for overload resolution.
+
+       * expression.cs : Update accordingly the various method calls.
+
+       This fixes 2 bugs filed against implicit user defined conversions 
+
+2002-05-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs: Track the result of the assignment.
+
+2002-05-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (MemberAccess): Improved error reporting for
+       inaccessible members.
+
+2002-05-22  Martin Baulig  <martin@gnome.org>
+
+       * makefile (mcs-mono2.exe): New target.  This is mcs compiled with
+       itself with debugging support.
+
+2002-05-22  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs ("System.Runtime.InteropServices.StructLayoutAttribute"):
+       Removed, this isn't needed anymore.
+
+2002-05-20  Martin Baulig  <martin@gnome.org>
+
+       * typemanager.cs (InitEnumUnderlyingTypes): "System.Char" can't
+       be underlying type for an enum.
+
+2002-05-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (InitEnumUnderlyingTypes): New helper function
+       that splits out the loading of just the core types.
+
+       * rootcontext.cs (ResolveCore): Split the struct resolution in
+       two, so we can load the enumeration underlying types before any
+       enums are used.
+
+       * expression.cs (Is): Bandaid until we fix properly Switch (see
+       bug #24985 for details).
+
+       * typemanager.cs (ImplementsInterface): The hashtable will contain
+       a null if there are no interfaces implemented.
+
+2002-05-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay (indexer_declarator): It is fine to have array
+       parameters
+
+2002-05-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs: (RegisterBuilder): New function used to register
+       TypeBuilders that implement interfaces.  Since
+       TypeBuilder.GetInterfaces (as usual) does not work with lame
+       Reflection.Emit. 
+       (AddUserType): register interfaces.
+
+       (ImplementsInterface): Use the builder_to_ifaces hash if we are
+       dealing with TypeBuilder.  Also, arrays are showing up as
+       SymbolTypes, which are not TypeBuilders, but whose GetInterfaces
+       methods can not be invoked on them!
+
+       * ecore.cs (ExplicitReferenceConversionExists): Made public.
+       (ImplicitReferenceConversionExists): Split out from
+       StandardConversionExists. 
+
+       * expression.cs (As): We were only implementing one of the three
+       cases for the as operator.  We now implement them all.
+       (Is): Implement the various other cases for Is as well.
+
+       * typemanager.cs (CACHE): New define used to control if we want or
+       not the FindMembers cache.  Seems to have a negative impact on
+       performance currently
+
+       (MemberLookup): Nested types have full acess to
+       enclosing type members
+
+       Remove code that coped with instance/static returns for events, we
+       now catch this in RealFindMembers.
+
+       (RealFindMembers): only perform static lookup if the instance
+       lookup did not return a type or an event.  
+
+2002-05-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs (CompoundAssign): We pass more semantic information
+       now to Compound Assignments than we did before: now we have all
+       the information at hand, and now we resolve the target *before* we
+       do the expression expansion, which allows the "CacheValue" method
+       to have the effect we intended (before, a [x] += 1 would generate
+       two differen ArrayAccess expressions from the ElementAccess,
+       during the resolution process).
+
+       (CompoundAssign.DoResolve): Resolve target and original_source here.
+
+2002-05-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ArrayAccess): dropped debugging information. 
+
+       * typemanager.cs: Small bug fix: I was always returning i_members,
+       instead of one of i_members or s_members (depending on which had
+       the content).
+
+       * assign.cs (IAssignMethod.CacheTemporaries): New method.  This
+       method is invoked before any code generation takes place, and it
+       is a mechanism to inform that the expression will be invoked more
+       than once, and that the method should use temporary values to
+       avoid having side effects
+
+       (Assign.Emit): Call CacheTemporaries in the IAssignMethod.
+
+       * ecore.cs (Expression.CacheTemporaries): Provide empty default
+       implementation.
+
+       * expression.cs (Indirection, ArrayAccess): Add support for
+       CacheTemporaries in these two bad boys. 
+
+       * ecore.cs (LoadFromPtr): figure out on our own if we need to use
+       ldobj or ldind_ref.  
+       (StoreFromPtr): Handle stobj as well.
+
+       * expression.cs (UnaryMutator): Share more code.
+
+       * typemanager.cs (FindMembers): Thanks to Paolo for tracking this
+       down: I was not tracking the Filter function as well, which
+       was affecting the results of the cache.
+
+2002-05-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs: Remove the hack to handle the CharSet property on
+       StructLayouts. 
+
+2002-05-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs (DoResolve): More uglyness, we now only try to
+       resolve the attribute partially, to extract the CharSet
+       information (only if we are a StructLayout attribute).  Otherwise 
+
+       (GetExtraTypeInfo): Add some code to conditionally kill in the
+       future this.   I am more and more convinced that the .NET
+       framework has special code to handle the attribute setting on
+       certain elements.
+
+       * expression.cs (IsParamsMethodApplicable): Revert my previous
+       foreach change here, it was wrong.
+
+2002-05-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: (pp_primary): Eat the ')' at the end.
+       (pp_expr): do not abort on unknown input, just return.
+       (eval): abort if there are pending chars.
+
+       * attribute.cs (Attribute.Resolve): Positional parameters are
+       optional.  Deal with that case.
+
+       * class.cs (DefineType): Call Attribute.GetExtraTypeInfo to fetch
+       the Ansi/Unicode/Auto information for the type.
+
+       (TypeContainer.DefineType): instantiate the EmitContext here, as
+       we will be using it during the type definition (to resolve
+       attributes) and during the emit phase.
+
+       * attribute.cs (Attribute.GetExtraTypeInfo): This routine is used
+       to pull type information out of the attributes
+
+       (Attribute.Resolve): track the constructor builder, and allow for
+       multiple invocations (structs and classes will use this).
+
+       * ecore.cs (MemberLookupFinal): new version with all the
+       parameters customizable.
+
+       * expression.cs (New.DoResolve): Use MemberLookupFinal to locate
+       constructors.  Return if the result value is null (as the error
+       would have been flagged already by MemberLookupFinal)
+
+       Do not allow instances of abstract classes or interfaces to be
+       created.
+
+       * class.cs: (MethodSignature.InheritableMemberSignatureCompare):
+       We have to compare the assembly property here when dealing with
+       FamANDAssem and Assembly access modifiers, because we might be
+       creating an assembly from *modules* (that means that we are not
+       getting TypeBuilders for types defined in other modules that are
+       part of this assembly).
+
+       (Method.Emit): If the method is marked abstract and has a body,
+       emit an error. 
+
+       (TypeContainer.DefineMembers): If both the defined member and the
+       parent name match are methods, then do not emit any warnings: let
+       the Method.Define routine take care of flagging warnings.  But if
+       there is a mismatch (method overrides something else, or method is
+       overriwritten by something, then emit warning).
+
+       (MethodSignature.MemberSignatureCompare): If the sig.ret_type is
+       set to null, this means `do not check for the return type on the
+       signature'. 
+
+       (Method.Define): set the return type for the method signature to
+       null, so that we get methods with the same name and parameters and
+       different return types.  This is used to flag warning 114 (you are
+       hiding a method, and you probably want to use the new/override
+       keywords instead).
+
+       * typemanager.cs (MemberLookup): Implemented proper access
+       control, closing a long standing set of bug reports.  The problem
+       was that the Framework only has two bits: Public and NonPublic,
+       and NonPublic includes private and protected methods, but we need
+       to enforce the FamANDAssem, FamOrAssem and Family. 
+
+2002-05-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (GotoCase): Return true: Ammounts to giving up
+       knowledge on whether we return or not, and letting the other case
+       be responsible for it.
+
+2002-05-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Do not load directories for each file processed, only
+       do it if there is a pattern.
+
+       * ecore.cs: Report readonly assigns here as well, as we might have
+       been resolved only by MemberAccess.
+
+       (SimpleName.SimpleNameResolve): Also be useful for LValue
+       resolution.   We need this to propagate assign to local readonly variables
+
+       * typemanager.cs: Use a ptrhashtable for the criteria, because we
+       do not want to reuse potential criteria memory.
+
+       * class.cs (MyEventBuilder): Set reflected_type;
+
+       * ecore.cs (Constantify): Added support for constifying bools.
+
+       (RootContext.LookupType): Added a cache for values looked up in
+       the declaration space.
+
+       * typemanager.cs (FindMembers): Now is a front-end to
+       RealFindMembers, and provides a two-level hashtable-based cache to
+       the request.  
+
+       15% performance improvement: from 22.5 to 19.2 seconds.
+
+       * expression.cs (IsParamsMethodApplicable): use foreach.
+       (Invocation.DoResolve): ditto.
+       (New.DoResolve): ditto.
+       (ArrayCreation.DoResolve): ditto.
+
+       * ecore.cs (FindMostEncompassingType): use foreach.
+
+       * delegate.cs (NewDelegate.DoResolve): Use foreach
+
+       * ecore.cs (Expression.FindMostSpecificSource): Use foreach.
+       (RemoveMethods): use foreach.
+
+       * expression.cs (Invocation.MakeUnionSet): Optimization: Use two
+       nested foreach statements instead of for, and also break out of
+       the inner loop once a match is found.
+
+       (Invocation.OverloadResolve): Use foreach, simplify the code. 
+
+2002-05-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * cfold.cs (BinaryFold): During an enumeration evaluation context,
+       we actually unwrap the expression to allow for extra information
+       to be extracted. 
+
+       * expression.cs: Use Shr_Un on unsigned operations. 
+
+2002-05-08  Ravi Pratap  <ravi@ximian.com>
+
+       * ecore.cs (FindMostEncompass*): Fix trivial bug where the set of 
+       applicable operators was not being considered correctly. This closes
+       the bug Miguel reported.
+
+Wed May 8 16:40:50 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * attribute.cs: check that the type derives from System.Attribute
+       and report the correct error in that case (moved the duplicate code to
+       its own method, too).
+
+Wed May 8 11:50:31 CEST 2002 Paolo Molaro <lupus@ximian.com>
+
+       * attribute.cs: lookup attribute type name as the spec says: first the
+       bare attribute name and then name + "Attribute" (nant compiles with
+       mcs after this fix).
+
+2002-05-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Unary.TryReduceNegative): Ah!  Tricky!  Tricky!
+       Because of the way we parse things, we should try to see if a
+       UIntConstant can fit in an integer.
+
+2002-05-07  Ravi Pratap  <ravi@ximian.com>
+
+       * ecore.cs (GetConversionOperators): Do not pick up op_True operators
+       when we are in an explicit context.
+
+       (ConvertReferenceExplicit): When converting from Iface type S to Class
+       T make sure the rules are implemented as an OR.
+
+       * parameter.cs (ParameterType): Make it a property for now although the
+       purpose really isn't anything immediate.
+
+       * expression.cs (Is*Applicable): Do better checking on the parameter type
+       of a ref/out parameter. The ones from the system assemblies are already 
+       marked with the correct type so we don't need to do any correction.
+
+       * ecore.cs (StandardConversionExists): Conversion from Interface types to 
+       the object type is standard too so include that.
+
+2002-05-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (StandardConversionExists): Augment with missing code:
+       deal with IntConstant, LongConstants and Enumerations.
+
+       * assign.cs: Report the error, instead of failing silently
+
+       * rootcontext.cs (AddGlobalAttributes): Track attributes on the
+       typecontainer that they are declared, because the
+       typecontainer/namespace will have the list of using clauses that
+       need to be applied.
+
+       Assembly Attributes were escaping the normal registration
+       mechanism. 
+
+       (EmitCode): Apply attributes within an EmitContext that represents
+       the container they were declared on.
+
+       * cs-parser.jay: Track bases for structs.  How did I get this wrong?
+
+2002-05-06  Ravi Pratap  <ravi@ximian.com>
+
+       * ecore.cs (FindMostEncompassingType, FindMostEncompassedType):
+       Revamp completely - make much cleaner as we now operate only
+       on a set of Types.
+
+       (FindMostSpecificSource, FindMostSpecificTarget): New methods
+       to implement the logic detailed in the spec more correctly.
+
+       (UserDefinedConversion): Update accordingly.
+
+2002-05-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs: Return flow analysis information up.
+
+       * cs-tokenizer.cs (adjust_real): Share code between LITERAL_DOUBLE
+       and the default.
+
+       (token): Do not consume an extra character before calling
+       decimal_digits.
+
+2002-05-06  Piers Haken        <piersh@friskit.com>
+
+       * cs-parser.jay: add 'override' attribute to System.Object.Finalize
+
+2002-05-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Constructor.Emit): Set the IsStatic flag in the
+       EmitContext during the instance constructor initializer
+       resolution, to stop access to instance variables.
+
+       This is mandated by the spec, last paragraph of the `constructor
+       initializers' section. 
+
+2002-05-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay, class.cs (Accessor): new class used to represent
+       an accessor (get or set).  In the past we used `null' to represent
+       a missing accessor.  But this is ambiguous because there was no
+       way to tell in abstract indexers/properties if one of them was
+       specified.
+
+       Now there is a way of addressing that.
+
+       * expression.cs (Indexers.GetIndexersForType): Use TypeManager.MemberLookup
+       instead of FindMembers.
+
+       * class.cs (TypeContainer.EmitFieldInitializer): Do not typecast
+       the result of Assign.Resolve as Assign, but rather as ExpressionStatement.
+
+       * attribute.cs: Treat indexers and properties as the same in terms
+       of applying attributes
+
+       * ecore.cs (FindMostEncompassedType): Use statically initialized
+       EmptyExpressions()s like we do elsewhere to avoid creating useless
+       objects (and we take this out of the tight loop).
+
+       (GetConversionOperators): Move the code to extract the actual
+       operators to a separate routine to clean things up.
+
+2002-05-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (FieldExpr): Remove un-needed tests for null, since now
+       events are always registered FieldBuilders.
+
+       * class.cs (FieldBase): New class shared by Fields 
+
+       * delegate.cs: If we are a toplevel delegate, use our full name.
+       If we are a nested delegate, then only use our tail name.
+
+2002-05-02  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (IsApplicable): Ensure that we add the "&" to
+       ref/out types before comparing it with the type of the argument.
+
+       (IsParamsMethodApplicable): Ditto.
+
+       (Argument.Type): Use TypeManager.LookupType instead of Type.GetType - 
+       silly me ;-)
+
+       * delegate.cs : Handle the case when we have more than one applicable
+       method. Flag an error only when we finish checking all.
+
+2002-05-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Add support for boolean static initializers.
+
+2002-05-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs: Use proper cast for Events, since we use a MyEventBuilder.
+
+       * parameter.cs (ComputeParameterTypes,
+       ComputeAndDefineParameterTypes): Better error handling: now we
+       clear the `types' cache if we fail during any of the type lookups.
+       We also return the status code correctly to our caller
+
+       * delegate.cs: If we fail to define a delegate, abort the extra
+       steps. 
+
+       * expression.cs (Binary.ResolveOperator): for
+       operator==(object,object) and operator !=(object, object) we also
+       have to verify that there is an implicit conversion from one to
+       the other.
+
+       (ArrayAccess.DoResolve): Array Access can operate on
+       non-variables. 
+
+2002-04-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs (CompoundAssign): A new class used as a "flag" that
+       the assignment actually is happening as part of a compound
+       assignment operator.
+
+       During compound assignment, a few new rules exist to enable things
+       like:
+
+       byte b |= 1 + 2
+
+       From the spec:
+
+       x op= y can be evaluated as x = (T) (x op y) (ie, an explicit cast
+       to the type of x) if y is implicitly convertible to the type of x,
+       and the operator is a builtin operator and the return type of the
+       operator is explicitly convertible to the type of x. 
+
+       * rootcontext.cs: Reset warning level to 2.  4 catches various
+       "interesting" features in mcs, we must clean this up at some
+       point, but currently am trying to kill other bugs ;-)
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Perform member lookups
+       in container classes as well.  
+
+       * expression.cs (Binary.ResolveOperator): Handle string case
+       before anything else (as operator overloading does emit an error
+       before doing anything else).
+
+       This code could go away when we move to a table driven model, but
+       i could not come up with a good plan last night.
+
+2002-04-30  Lawrence Pit <loz@cable.a2000.nl>
+
+       * typemanager.cs (CSharpName): reimplementation using regex.
+       * class.cs: added null check for fields in Emit
+       * rootcontext.cs: set warninglevel to 4
+
+2002-04-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (CSharpName): reimplemented with Lupus
+       suggestion.
+
+2002-04-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (If): correclty implement Resolve, because we were
+       not catching sem errors in there.  The same process is needed
+       everywhere else. 
+       (Return, StatementExpression, For, While, Do, Throw, Lock): Implement Resolve
+
+
+       (Statement.Warning_DeadCodeFound): Factorize code.
+       (While): Report dead code here too.
+
+       (Statement): Added Resolve virtual method to allow
+       for resolution split from the emit code.
+
+2002-04-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (EmitBoolExpression): No longer try to resolve the
+       expression here.    
+       (MakeBoolean): New utility function that resolve, implicitly
+       converts to boolean and tags the expression. 
+
+
+       (If, Do): Implement dead code elimination.
+       (While): Implement loop inversion
+
+       (Do, While, For, If): Resolve the expression prior to calling our
+       code generation.
+
+2002-04-22  Lawrence Pit <loz@cable.a2000.nl>
+
+       * class.cs:
+         - added method Report28 (warning: program has more than one entry point)
+         - added method IsEntryPoint, implements paragraph 10.1 of the spec
+         - modified method Method.Define, the part at the end of the method
+
+       * rootcontext.cs: added static public Location EntryPointLocation;
+         
+       * ../errors/cs0028.cs : Add test case for the above warning.              
+
+       * typemanager.cs:
+         - modified method CSharpName to allow arrays of primitive type to
+           be printed nicely (e.g. instead of System.Int32[][] it now prints
+           int[][])
+         - added method CSharpSignature: returns the signature of a method
+           in string format to be used in reporting errors, warnings, etc.
+
+       * support.cs: InternalParameters.ParameterDesc variable tmp initialized
+       with String.Empty.
+
+2002-04-26  Ravi Pratap  <ravi@ximian.com>
+
+       * delegate.cs (Define): Fix extremely silly bug where I was
+       setting the type of the 'object' parameter of the BeginInvoke
+       method to System.IAsyncResult instead of System.Object ;-)
+
+2002-04-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (ConstructorInitializer.Resolve): Also use DeclaredOnly
+       here. 
+
+       (Constructor.Emit): return if we fail to initialize the
+       constructor.  Another door closed!  
+
+       * expression.cs (New.DoResolve): Improve error message (from -6 to
+       1501).  Use DeclaredOnly lookup to find the exact constructor.
+
+       * typemanager.cs (MemberLookup): If DeclaredOnly is set, do not
+       loop.  This is useful.
+
+       * cs-parser.jay: Adjust the default parameters so that destructors
+       have the proper signature.
+
+2002-04-26  Martin Baulig  <martin@gnome.org>
+
+       * driver.cs (LoadAssembly): If `assembly' contains any characters
+       which are only valid in path names and not in assembly names
+       (currently slash, backslash and point), use Assembly.LoadFrom ()
+       instead of Assembly.Load () on the `assembly' (before iteration
+       over the link_paths).
+
+2002-04-26  Martin Baulig  <martin@gnome.org>
+
+       * cs-tokenizer.cs (is_hex): Correctly handle lowercase chars.
+
+2002-04-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Property): use the new typemanager.MemberLookup
+
+       (TypeContainer.MemberLookup): Implement using the
+       TypeManager.MemberLookup now. 
+
+       * typemanager.cs: Make MemberLookup a function of the TypeManager,
+       and return MemberInfos, so that these can be used without an
+       EmitContext (what we had before).
+
+2002-04-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Fix the case where the argument to params if the
+       type of the params.  I omitted handling this before.   Fixed
+
+2002-04-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Call BootCorlib_PopulateCoreType
+
+       * class.cs (Property.CheckBase): Check for properties only, not
+       for all members. 
+
+       * interface.cs: Temporary hack: try/catch around the
+       CustomAttributeBuilder, because I am getting an exception that I
+       do not understand.
+
+       * rootcontext.cs (BootCorlib_PopulateCoreType): Populate some
+       types whose definitions are required to be there (attributes are
+       defined before standard types).
+
+       Compute definitions as we boot the various types, as they are used
+       immediately (value_type class will need object_type, but if we do
+       not initialize object_type, we will pass a null, which will let
+       the runtime pick the System.Object from the existing corlib, which
+       is not what we want).
+
+2002-04-22  Patrik Torstensson <totte@labs2.com>
+
+       * cs-tokenizer.cs: fixed a number of trim() issues.
+
+2002-04-22  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Argument.Type): Ensure that we return the correct
+       type when we have out or ref parameters [in which case we 
+       append a "&"].
+
+2002-04-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Property, Indexer): Allow extern modifier in there. 
+
+       * typemanager.cs (InitBaseTypes): Initializes object_type and
+       value_type, since those will be used early on during the bootstrap
+       process to compile corlib.
+
+       (InitCoreTypes): Move code from here to InitBaseTypes.
+
+2002-04-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (PropertyExpr): Optimize calls to Array::get_Length on
+       single-dimension arrays as using the ldlen opcode.  
+
+       Daniel Lewis discovered this optimization.  
+
+       * typemanager.cs: Add signature for System.Array::get_Length
+
+2002-04-20  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * statement.cs: report the error when the foreach does not apply to an
+       array nor a collection.
+
+2002-04-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Add implicit conversions to the operator ~.
+
+       * constant.cs (DecimalConstant.Emit): Emit decimal value.
+
+       * typemanager.cs: Locate the decimal constructor.
+
+2002-04-17  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * attribute.cs: use the new property of TypeOf.
+       * expression.cs: added 'get' property around typearg.
+
+       These changes fix a build breaker reported by NickD. Is this the
+       correct way to fix?  If not, please, revert my changes and make it
+       work :-).
+
+2002-04-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * attribute.cs: Add support for typeof in attribute invocations.
+       I am not sure that this is right though.
+
+2002-04-14  Duncan Mak  <duncan@ximian.com>
+
+       * cfold.cs (BinaryFold): Catch DivideByZeroException in the
+       Binary.Operator.Division case.
+
+2002-04-13  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (DefineType): Ensure that we do a proper check on
+       attribute types and also register it with the TypeManager.
+
+       (TypeContainer.Targets): The default for attribute types is
+       AttributeTargets.All.
+
+       * attribute.cs (ApplyAttributes): Registering the attribute type
+       is done elsewhere, not when we discover we have a Usage attribute.
+
+2002-04-12  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (VerifyArgumentsCompat): Implement Miguel's suggestion
+       and get rid of is_delegate parameter.
+
+       * everywhere : update.
+
+2002-04-12  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (compilation_unit): Revamp completely to use
+       some new ideas that I got from Rhys' grammar to solve the problems
+       with assembly level attributes.
+
+       (outer_declaration): New grammar production.
+
+       (attribute_sections): Add.
+
+       (opt_attributes): Base on attribute_sections
+
+       (namespace_declaration): Allow opt_attributes to tackle the case
+       when we have assembly level attributes - we are clever in this
+       regard now ;-)
+
+       * attribute.cs (ApplyAttributes): Do not worry about assembly 
+       attributes in the non-global context.
+
+       * rootcontext.cs (AddGlobalAttributes): Go back to using this
+       instead of SetGlobalAttributes.
+
+       * class.cs, rootcontext.cs : Ensure we define and generate 
+       attribute types before anything else.
+
+       * attribute.cs (CheckAttribute and GetValidPlaces): Handle the exception
+       and flag the new error -20 for the case when the attribute type
+       does not have valid targets specified. csc does not catch this.
+
+       * ../errors/errors.txt : update for error # -20
+
+2002-04-11  Ravi Pratap  <ravi@ximian.com>
+
+       * support.cs (InternalParameters.ParameterModifier): Do some null
+       checking and return sane values.
+
+       * class.cs (Method.Define): If we are a PInvoke method, ensure
+       that we are static and extern. Report error # 601
+
+       * ../errors/cs0601.cs : Add test case for the above error.
+
+2002-04-07  Ravi Pratap  <ravi@ximian.com>
+
+       * rootcontext.cs (attribute_types): We need to keep type of
+       all attribute types separately and emit code for them first.
+
+       (RegisterAttribute) : Implement.
+
+       * class.cs (DefineType): Check if the current Type is a custom
+       attribute type and register it accordingly.
+
+       * rootcontext.cs (AddGlobalAttributes): Fix silly bug where we were
+       adding the first attribute twice and rename to
+
+       (SetGlobalAttributes): this.
+
+       * rootcontext.cs (NamespaceLookup): Run through the aliases too and perform
+       lookups.
+
+       * attribute.cs (ApplyAttributes): Take an additional argument telling us
+       if we are processing global arguments. Hmm, I am unsure of this.
+
+2002-04-12  Gonzalo Paniagua Javier <gonzalo@ximian.com>
+
+       * expression.cs: added static array of strings to avoid calling
+       Enum.ToString () for Operator in Binary. Significant recover of
+       performance.
+
+2002-04-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (FindMembers): Allow the Builders of the various
+       members to be null.  If they are skip them.  This only happens
+       during the PInvoke declaration.
+
+2002-04-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * parameter.cs (Parameters.ComputeParameterTypes): Flag the
+       failure, so we do not keep going afterwards.
+
+       * expression.cs: (Invocation.OverloadResolve): I believe Ravi
+       wanted to pass `false' as the `is_delegate' argument.  If this is
+       the case, why not use delegate_type == null to mean `is_delegate =
+       false' and anything else as is_delegate = true.
+
+Tue Apr  9 05:40:12  2002 Piers Haken <piersh@friskit.com>
+
+       * statement.cs: fixed SimpleSwitchEmit to make 'goto case' goto the
+       code for the section, not the beginning of the tests.
+
+2002-04-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * cfold.cs: Handle operator + (Enum x, Underlying x) 
+
+       * expression.cs (Binary): same.  Warn about errors where we have
+       Enum/Enum in operator + as well.
+
+Mon Apr  8 06:29:03  2002 Piers Haken <piersh@friskit.com>
+
+       * statement.cs:
+               - added support for switch(bool)
+               - optimize loading of I8/U8 constants (ldc.i4, iconv_i8)
+               - add TableSwitchEmit() to handle table-based switch statements
+
+2002-04-05  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Invocation.OverloadResolve): Factor out code which
+       does parameter compatibility checking with arguments so that we can 
+       re-use the code even from Delegate.VerifyApplicability
+
+       (VerifyArgumentsCompat): Move above code here.
+
+       * delegate.cs (VerifyApplicability): Get rid of duplicate code
+       and instead make a call to the above method.
+
+2002-03-31  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (attribute_type): Corresponds to System.Attribute.
+       We use it to keep track of classes which are attribute types.
+
+2002-04-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * delegate.cs (Delegate.Define): Correctly define the types in the
+       presence of fixed and array parameters.
+
+       * class.cs (TypeContainers.FindMembers): Use NonPublic flag while
+       doing FindMembers.
+
+       * ecore.cs (Expression.MemberLookup): Reset binding flags to not
+       include NonPublic after the first iteration.
+
+       * class.cs (Indexer.CheckBase): Only check if both parents are
+       non-null. 
+
+       * cs-parser.jay (accessor_body): If empty, set to null.
+
+       * ecore.cs (SimpleName.SimpleNameResolve): We did not have the
+       same code path here to resolve constants names that we did have in
+       MemberAccess.DoResolve.  There is too much code duplicated here.
+
+2002-04-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs, makefile: Drop Statementcollection and just use ArrayLists
+
+       * ecore.cs: Optimize UserDefinedConversion by minimizing the calls
+       to MakeUnionSet.
+
+       * cs-tokenizer.cs: Reuse a single StringBuilder for assembling
+       tokens, numbers and strings.
+
+       * ecore.cs (MethodGroupExpr): Make Emit warn about missing
+       parenthesis.
+
+       * delegate.cs: Use ComputeAndDefineParameterTypes for both the
+       asyncronous parameters and the regular parameters.  
+
+       * codegen.cs (CodeGen.Init): Use the constructor that allows us to
+       specify the target directory.
+
+       * expression.cs: (This.DoResolve): Simplify
+       (As.Emit): Optimize, do not generate IsInst if the expression is
+       always of the given type.
+
+       (Is.DoResolve): Bug fix, we were reporting both always/never for
+       the is expression.
+
+       * (Invocation.MakeUnionSet): Simplify vastly and optimize, we were
+       creating too many unnecessary arrays.
+
+2002-03-31  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (EmitFieldInitializer): Use Assign expression to assign
+       fields instead of rolling our own initializer.   Takes care of all
+       implicit conversions, and drops unnecessary static checks/argument.
+
+2002-03-31  Dick Porter  <dick@ximian.com>
+
+       * driver.cs: use the GetDirectories() return values properly, and
+       use "/" as path separator.
+
+2002-03-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Unary): Optimize - - expr into expr.
+       (Binary): Optimize a + (-b) into a -b.
+
+       * codegen.cs (CodeGen): Made all methods static.
+
+2002-03-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs: 
+
+       * decl.cs: Rename `definition' into `TypeBuilder' and drop the
+       TypeBuilder property.
+
+       * cs-parser.jay: Drop the use of RecordXXX and use RecordDecl
+       instead. 
+
+       * tree.cs: Removed the various RecordXXXX, and replaced with a
+       single RecordDecl.  Removed all the accessor methods, and just
+       left a single access point Type 
+
+       * enum.cs: Rename DefineEnum to DefineType.
+
+       * decl.cs: New abstract method `DefineType' used to unify the
+       Defines for Enumerations, Interfaces, TypeContainers and
+       Delegates.
+
+       (FindType): Moved LookupInterfaceOrClass here.  Moved the
+       LookupBaseClasses method that used to live in class.cs and
+       interface.cs here, and renamed to FindType.
+
+       * delegate.cs: Implement DefineType.  Take advantage of the
+       refactored pattern for locating the parent builder without taking
+       the parent_builder argument (which we know does not work if we are
+       nested, and triggering a toplevel definition).
+
+2002-03-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * decl.cs (MemberCore.CheckMethodAgainstBase): Test if the
+       accessibility of a member has changed during override and report
+       an error if so.
+
+       * class.cs (Method.Define, Property.Define): Only complain on
+       overrides if the method is private, any other accessibility is
+       fine (and since we just checked the permission is the same, we are
+       good to go).
+
+       * cs-tokenizer.cs: only line, region, endregion, if, endif, else
+       and elif are processed always.  The other pre-processing
+       directives are only processed if we are "taking" the path
+
+2002-03-29  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (Method.Emit): Only emit symbolic debugging info if the
+       current location is not Null.
+
+       * codegen.cs (CodeGen.SaveSymbols): Split out symbol writing code into
+       a separate method so we can profile it.
+
+       * driver.cs (ShowTime): We need to use `(int) span.TotalSeconds' since
+       `span.Seconds' are just seconds, but no minutes or hours.
+       (MainDriver): Profile the CodeGen.SaveSymbols calls.
+
+2002-03-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Method.Define), (Property.Define), (Indexer.Define):
+       Remove the gratuitous set of Final:
+
+                               // If an interface implementation, then we can set Final.
+                               if (((flags & MethodAttributes.Abstract) == 0) &&
+                                   implementing.DeclaringType.IsInterface)
+                                       flags |= MethodAttributes.Final;
+
+       I do not know what I was smoking when I used that.
+
+
+       * cs-parser.jay, delegate.cs: Make Delegate be a DeclSpace, first
+       step into fixing the name resolution issues for delegates and
+       unifying the toplevel name resolution.
+
+2002-03-28  Martin Baulig  <martin@gnome.org>
+
+       * class.cs (Method.Emit): If we have a symbol writer, call its
+       OpenMethod(), CloseMethod() and SetMethodSourceRange() methods to
+       tell it about the current method.
+
+       * codegen.cs (EmitContext.Mark): New public method. Tell the symbol
+       writer that we're going to emit the first byte of IL code for a new
+       statement (a new source line).
+       (EmitContext.EmitTopBlock): If we have a symbol writer, call
+       EmitContext.Mark() before emitting any code.
+
+       * location.cs (SymbolDocument): Return null when we're Null.
+
+       * statement.cs (Statement): Moved the `Location loc' variable here.
+       (Statement.EmitBoolExpression): If we have a symbol writer, call
+       ec.Mark() before emitting any code to tell it that we're at the
+       beginning of a new statement.
+       (StatementExpression): Added `Location' argument to the constructor.
+       (Block): Added public readonly variable `StartLocation' and public
+       variable `EndLocation'.  The latter is to be set using SetEndLocation().
+       (Block): Added constructor which takes a start and end location.
+       (Block.SetEndLocation): New method. This sets the end location.
+       (Block.EmitMeta): If we have a symbol writer, tell it the names of the
+       local variables we create.
+       (Block.Emit): If we have a symbol writer, call ec.Mark() before emitting
+       each statement and do also mark the begin and end of the block.
+
+       * cs-parser.jay (block : OPEN_BRACE): Use the new `Block' constructor to
+       tell it the current lexer.Location, use Location.Null for the end of the
+       block.
+       (block : OPEN_BRACE opt_statement_list CLOSE_BRACE): When closing the
+       current block, set its end location using SetEndLocation().
+       (statement_expression): StatementExpression constructor now takes the
+       lexer.Location as additional argument.
+       (for_statement, declare_local_variables): Likewise.
+       (declare_local_variables): When creating a new implicit block, use the
+       new Block constructor and pass it the lexer.Location.
+
+2002-03-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (Expression.MemberLookup): On interfaces, lookup
+       members also on the parent interfaces recursively.
+
+2002-03-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * report.cs: Use new formats, since Gonzalo finished the missing
+       bits. 
+
+       * expression.cs (Binary.ResolveOperator): added missing operator|
+       operator& and operator^ for bool/bool.
+
+       * cs-parser.jay: CheckDef now takes a Location argument that is
+       used to report errors more precisly (instead of reporting the end
+       of a definition, we try to track something which is a lot closer
+       to the source of the problem).
+
+       * cs-tokenizer.cs: Track global token use, so we can properly flag
+       the use of #define/#undef after the first token has been seen.
+
+       Also, rename the reportXXXX to Error_DescriptiveName
+
+       * decl.cs (DeclSpace.IsTopLevel): Move property here from
+       TypeContainer, so that Enum and Interface can use this too.
+
+       * class.cs (TypeContainer.LookupInterfaceOrClass,
+       GetInterfaceOrClass, GetClassBases, DefineType): Drop the
+       `builder' argument.  Typically this was used to pass the parent
+       builder (a ModuleBuilder or a TypeBuilder from whoever triggered
+       the definition).  
+
+       The problem is that a nested class could trigger the definition of
+       a toplevel class, and the builder would be obviously wrong in that
+       case. 
+
+       So we drop this argument, and we compute dynamically the
+       TypeBuilder/ModuleBuilder (the correct information was available
+       to us anyways from DeclSpace.Parent)
+
+       * interface.cs (Interface.DefineInterface): Drop builder
+       parameter cleanup like class.cs
+
+       * enum.cs (Enum.DefineEnum): Drop builder parameter.  Clean up
+       like class.cs
+
+       * statement.cs (Switch.EmitObjectInteger): Emit short/ushort
+       values. 
+
+       (Try.Emit): Propagate the returns value from the statement.
+
+       (Return.Emit): Even if we are leavning 
+
+       * driver.cs: Catch IOExpcetion for Directory.GetFiles as well.
+
+       * modifiers.cs: Fix the computation of MethodAttributes flags.
+
+Tue Mar 26 21:14:36 CET 2002 Paolo Molaro <lupus@ximian.com>
+
+       * driver.cs: allow compilation of files that start with '/'.
+       Add a default case when checking the argument of --target.
+
+2002-03-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * interface.cs: Implement the same search algorithm for types in
+       the interface code.
+
+       * delegate.cs: Do not allow multiple definition.
+
+       * Recovered ChangeLog that got accidentally amputated
+
+       * interface.cs (Interface.DefineInterface): Prevent from double definitions.
+
+       * rootcontext.cs: Load manually enum to allow core classes to
+       contain enumerations.
+
+       * enum.cs, ecore.cs, driver.cs, attribute.cs, class.cs, expression.cs:
+       Update to new static methods in TypeManager.
+
+       * typemanager.cs (GetMethod, GetConstructor): Use our
+       implementation of FindMembers to find the members, since during
+       corlib compilation, the types are TypeBuilders and GetMethod and
+       GetConstructor do not work.
+
+       Make all methods in TypeManager static.
+
+       (InitCodeHelpers): Split the functionality from
+       the InitCodeTypes function.
+
+       * driver.cs: Call InitCodeHelpers after we have populated the
+       types. 
+
+       * cs-parser.jay (delegate_declaration): we did not used to compute
+       the delegate name correctly for void delegates.
+
+2002-03-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs (RootContext): Init the interface_resolve_order
+       and type_container_resolve_order always.
+
+       (ResolveCore, BootstrapCorlib_ResolveClass,
+       BootstrapCorlib_ResolveStruct): New functions to bootstrap the
+       compiler when compiling with --nostdlib
+
+       * class.cs (TypeContainer.DefineType): Check that our parent is
+       not null.  This test is most important when we are bootstraping
+       the core types.
+
+       * codegen.cs: Split out the symbol writing code.
+
+2002-03-25  Martin Baulig  <martin@gnome.org>
+
+       * driver.cs (-g): Made -g an alias for --debug.
+
+2002-03-24  Martin Baulig  <martin@gnome.org>
+
+       * codegen.cs (SymbolWriter): New public variable. Returns the
+       current symbol writer.
+       (CodeGen): Added `bool want_debugging_support' argument to the
+        constructor. If true, tell the ModuleBuild that we want debugging
+       support and ask it for the ISymbolWriter.
+       (Save): If we have a symbol writer, call it's Close() method after
+       saving the assembly.
+
+       * driver.c (--debug): New command line argument to create a
+       debugger information file.
+
+       * location.cs (SymbolDocument): New public property. Returns an
+       ISymbolDocumentWriter object for the current source file or null
+       if we don't have a symbol writer.
+
+2002-03-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs (LoadAssembly): Correctly return when all the paths
+       have been tried and not before.
+
+       * statement.cs (Switch.Emit): return the actual coverage for this
+       statement (returns/not-returns)
+
+       (Switch.SimpleSwitchEmit): Do not generate jumps to the end of the
+       switch of the statement if we are the last switch section.  That
+       kills two problems: try/catch problems (we used to emit an empty
+       nop at the end) and switch statements where all branches would
+       return. 
+
+2002-03-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Add default assemblies (the equivalent to the
+       Microsoft CSC.RSP file)
+
+       * cs-tokenizer.cs: When updating `cols and setting it to zero,
+       also update tokens_seen and set it to false.
+
+       * driver.cs: Implement --recurse for Mike.
+
+       * driver.cs (SplitPathAndPattern): Small bug fix, I was not
+       correctly splitting out the paths.
+
+2002-03-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * interface.cs (Interface.PopulateProperty): Instead of using
+       `parent' as the declaration space for the set parameters, use
+       `this' 
+
+       * support.cs (InternalParameters): InternalParameters constructor
+       takes a DeclSpace instead of a TypeContainer.
+
+       * expression.cs (ArrayCreation.EmitDynamicInitializers): If value
+       types are being initialized, load the address of it before calling
+       the function.  
+
+       (New): Provide a mechanism to disable the generation of local
+       value type temporaries when the caller will be providing us with
+       an address to store it.
+
+       (ArrayCreation.EmitDynamicInitializers): Use it.
+
+2002-03-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Invocation.EmitArguments): Only probe for array
+       property if there is more than one argument.  Sorry about that.
+
+       * class.cs (Invocation.EmitArguments): Fix to emit arguments for
+       empty param arrays.
+
+       * class.cs (Method.LabelParameters): Fix incorrect code path that
+       prevented the `ParamArrayAttribute' from being applied to the
+       params attribute.
+
+2002-03-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * support.cs (ReflectionParameters): Correctly compute whether the
+       last argument is a params array.  Fixes the problem with
+       string.Split ('a')
+
+       * typemanager.cs: Make the assemblies array always be non-null
+       (empty, but non-null)
+
+       * tree.cs (RecordDecl): New function that abstracts the recording
+       of names.  This reports error 101, and provides a pointer to the
+       previous declaration.  Fixes a crash in the compiler.
+
+       * cs-parser.jay (constructor_declaration): Update to new grammar,
+       and provide a constructor_body that can be empty.
+
+2002-03-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Add support for --resources.
+
+       * expression.cs: (FetchGetMethod, FetchAddressMethod, EmitAssign):
+       Make all types for the various array helper methods be integer.
+
+       * ecore.cs (Expression.ConvertNumericExplicit): Pass the
+       CheckState to ConvCast.
+
+       (ConvCast): Now it takes a `checked' state argument, to avoid
+       depending on the emit context for the conversion, and just using
+       the resolve time setting.
+
+       * expression.cs (ArrayCreation.EmitArrayArguments): New function,
+       instead of Invocation.EmitArguments.  We do not emit the original
+       arguments, instead we emit those which have been converted to
+       unsigned int expressions.
+
+       * statement.cs (Block.EmitMeta): Drop tracking of indexes.
+
+       * codegen.cs: ditto.
+
+       * expression.cs (LocalVariableReference): Drop the use of the
+       Store function that depended on the variable index.
+
+       * statement.cs (VariableInfo): Drop the `Idx' property from this
+       class, as this is not taking into account the indexes for
+       temporaries tat we generate during the execution, getting the
+       indexes wrong.
+
+       * class.cs: First emit class initializers, then call the parent
+       constructor. 
+
+       * expression.cs (Binary): Fix opcode emision.
+       (UnaryMutator.EmitCode): Support checked code generation
+
+       * ecore.cs (MemberLookup): TypeManager.FindMembers will return
+       matches for events for both the Static and Instance scans,
+       pointing to the same element.   Fix that.
+
+2002-03-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs (ResolveTree): Always set the
+       interface_resolve_order, because nested interfaces will be calling
+       into us.
+
+       * class.cs (GetInterfaceOrClass): Track the same resolution
+       process used by TypeManager.LookupType.  This fixes the nested
+       type lookups in class declarations (separate path from
+       LookupType). 
+
+       (TypeContainer.DefineType): Also define nested interfaces.
+       (TypeContainer.RegisterOrder): New public function used to
+       register the order in which child interfaces need to be closed.
+
+       Nested interfaces need to be closed after their parents have been
+       created. 
+
+       * interface.cs (InterfaceAttr): Put all the logic for computing
+       the interface attribute here. 
+
+       (DefineInterface): Register our interface order with the
+       RootContext or with the TypeContainer depending on the case.
+
+2002-03-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: rework foreach statement to work with the new
+       changes to the policy on SimpleNames.
+
+       * report.cs: support Stacktrace on warnings as well.
+
+       * makefile: drop --unsafe and /unsafe from the compile.
+
+2002-03-13  Ravi Pratap  <ravi@ximian.com>
+
+       * ecore.cs (StandardConversionExists): Modify to take an Expression
+       as the first parameter. Ensure we do null -> reference type conversion
+       checking.
+
+       * Everywhere : update calls accordingly, making use of MyEmptyExpr to store
+       temporary Expression objects.
+
+Wed Mar 13 12:32:40 CET 2002 Paolo Molaro <lupus@ximian.com>
+
+       * interface.cs: workaround bug in method overloading resolution
+       (there is already a bugzilla bug for it).
+
+2002-03-12  Miguel de Icaza  <miguel@ximian.com>
+
+       We could also solve this problem by having a separate path for
+       performing type lookups, instead of DoResolve, we could have a
+       ResolveType entry point, and only participating pieces of the
+       production (simplename, deref, array) would implement this. 
+
+       * codegen.cs (EmitContext): New field OnlyLookupTypes used to
+       signal SimpleName to only resolve type names and not attempt to
+       resolve anything else.
+
+       * expression.cs (Cast): Set the flag.
+
+       * ecore.cs (SimpleName): Use the OnlyLookupTypes flag
+
+       * class.cs: Only report 108 if there is no `new' modifier.
+
+       * cs-parser.jay: rework foreach statement to work with the new
+       changes to the policy on SimpleNames.
+       
+       * report.cs: support Stacktrace on warnings as well.
+
+       * makefile: drop --unsafe and /unsafe from the compile.
+
+2002-03-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Perform local variable
+       lookups here, instead of doing that at parse time.  This means
+       that our grammar will not introduce `LocalVariableReferences' as
+       expressions at this point.  That solves the problem of code like
+       this:
+
+       class X {
+          static void Main ()
+          { int X = 1;
+           { X x = null }}}
+
+       This is only half the fix.  The full fix requires parameters to
+       also be handled in this way.
+
+       * Everywhere: Use ec.DeclSpace on calls to LookupType, as this
+       makes the use more obvious of the DeclSpace.  The
+       ec.TypeContainer.TypeBuilder is now only used to pull the
+       TypeBuilder for it.
+
+       My theory is that I can get rid of the TypeBuilder completely from
+       the EmitContext, and have typecasts where it is used (from
+       DeclSpace to where it matters).  
+
+       The only pending problem is that the code that implements Aliases
+       is on TypeContainer, and probably should go in DeclSpace.
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Perform local variable
+       lookups here, instead of doing that at parse time.  This means
+       that our grammar will not introduce `LocalVariableReferences' as
+       expressions at this point.  That solves the problem of code like
+       this:
+
+       class X {
+          static void Main ()
+          { int X = 1;
+           { X x = null }}}
+
+       This is only half the fix.  The full fix requires parameters to
+       also be handled in this way.
+
+       * class.cs (Property.DefineMethod): When implementing an interface
+       method, set newslot, when implementing an abstract method, do not
+       set the flag (before we tried never setting it, or always setting
+       it, which is the difference).
+       (Indexer.DefineMethod): same.
+       (Method.DefineMethod): same.
+
+       * ecore.cs: Only set the status used flag if we get back a Field.
+
+       * attribute.cs: Temporary hack, so Paolo can keep working.
+
+2002-03-08  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (Attribute.UnmanagedType): This is to keep track of
+       the unmanaged type in the case we have a MarshalAs attribute.
+
+       (Resolve): Handle the case when we are parsing the special MarshalAs
+       attribute [we need to store the unmanaged type to use later]
+
+       * typemanager.cs (marshal_as_attr_type): Built in type for the 
+       MarshalAs Attribute.
+
+       * attribute.cs (ApplyAttributes): Recognize the MarshalAs attribute 
+       on parameters and accordingly set the marshalling info.
+
+2002-03-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs: Optimizing slightly by removing redundant code after
+       we switched to the `NoTypes' return value.
+       (Property.DefineMethod): use NoTypes here too.
+
+       This fixes the bug I introduced in my last batch of changes.
+
+2002-03-05  Ravi Pratap  <ravi@ximian.com>
+
+       * tree.cs (RecordEnum): Add. We now keep track of enums too.
+
+       * class.cs (LookupInterfaceOrClass): Check against the list of recorded
+       Enums since those are types too. 
+
+       * cs-parser.jay (enum_declaration): Record enums as we parse them.
+
+       * enum.cs (DefineEnum): Return if the TypeBuilder has already been defined 
+       thanks to a call during the lookup process.
+
+2002-03-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Foreach): Lots of work to accomodate a particular
+       kind of foreach statement that I had not kept in mind.  It is
+       possible to have foreachs on classes that provide a GetEnumerator
+       method that return objects that implement the "pattern" for using
+       a foreach, there is no need to support GetEnumerator
+       specifically. 
+
+       This is needed to compile nant.
+
+       * decl.cs: Only report 114 if the member is not `Finalize' and if
+       the warning level is at least 2.
+
+       * class.cs: Moved the compare function from Method to
+       MethodSignature. 
+
+       (MethodSignature.InheritableMemberSignatureCompare): Add new
+       filter function that is used to extract inheritable methods from a
+       class. 
+
+       (Method.Define): Use the new `inheritable_method_signature_filter'
+       delegate
+
+       * cs-tokenizer.cs (get_cmd_arg): Do not add white space to the
+       command. 
+
+2002-03-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (Expression.ConvertReferenceExplicit): Removed dead code.
+
+       * cs-parser.jay: Add opt_semicolon to the interface declaration.
+
+       * expression.cs: Pass location information to
+       ConvertImplicitStandard. 
+
+       * class.cs: Added debugging code to track return values from
+       interfaces. 
+
+2002-03-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Is.DoResolve): If either side of the `is' is an
+       interface, do not flag the warning.
+
+       * ecore.cs (ImplicitReferenceConversion): We need a separate test
+       for interfaces
+
+       * report.cs: Allow for --fatal to be used with --probe.
+
+       * typemanager.cs (NoTypes): Move the definition for the empty Type
+       array here. 
+
+       * class.cs (TypeContainer.FindMembers): Also look for methods defined by
+       properties. 
+       (TypeContainer.DefineProxy): New function used to proxy to parent
+       implementations when implementing interfaces.
+       (TypeContainer.ParentImplements): used to lookup if our parent
+       implements a public function that is required by an interface.
+       (TypeContainer.VerifyPendingMethods): Hook this up.
+
+       * typemanager.cs (TypeManager, AddModule, AddAssembly): Make the
+       `modules' and `assemblies' arraylists into arrays.  We only grow
+       these are the very early start up of the program, so this improves
+       the speedof LookupType (nicely measured).
+
+       * expression.cs (MakeByteBlob): Replaced unsafe code with
+       BitConverter, as suggested by Paolo.
+
+       * cfold.cs (ConstantFold.Binary): Special case: perform constant
+       folding of string concatenation, but if either side is a string,
+       and the other is not, then return null, and let the runtime use
+       the concatenation on the string plus the object (using
+       `Object.ToString'). 
+
+2002-03-04  Miguel de Icaza  <miguel@ximian.com>
+
+       Constant Folding has been implemented now.
+
+       * expression.cs (Unary.Reduce): Do not throw an exception, catch
+       the error instead on types that are not supported in one's
+       complement. 
+
+       * constant.cs (Constant and all children): New set of functions to
+       perform implict and explicit conversions.
+
+       * ecore.cs (EnumConstant): Implement the new functions to perform
+       conversion by proxying to the child expression.
+
+       * codegen.cs: (ConstantCheckState): Constant evaluation has its
+       own separate setting that can not be turned off from the command
+       line using --unchecked or --checked and is only controlled using
+       the checked/unchecked statements and expressions.  This setting is
+       used by the constant folder to flag errors.
+
+       * expression.cs (CheckedExpr, UncheckedExpr): Set the
+       ConstantCheckState as well.   
+
+       During Resolve, they also have to flag the state, because the
+       constant folder runs completely in the Resolve phase.
+
+       * statement.cs (Checked, Unchecked): Set the ConstantCheckState as
+       well.
+
+2002-03-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * cfold.cs: New file, this file contains the constant folder.
+
+       * ecore.cs (IMemoryLocation.AddressOf): Now takes an extra
+       argument to track whether we are using the resulting address to
+       load or store a value and provide better error messages. 
+
+       (FieldExpr.Emit, FieldExpr.EmitAssign, FieldExpr.AddressOf): Use
+       new AddressOf arguments.
+
+       * statement.cs (Foreach.EmitCollectionForeach): Update
+
+       * expression.cs (Argument.Emit): Call AddressOf with proper
+       arguments to track usage.
+
+       (New.DoEmit): Call AddressOf with new arguments.
+
+       (Unary.Emit): Adjust AddressOf call.
+
+2002-03-01  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (member_access): Change the case for pre-defined types
+       to use a MemberAccess instead of a SimpleName. Thanks to Felix again for 
+       this suggestion.
+
+       * class.cs (Operator::Emit): If we are abstract or extern, we don't have
+       a method body.
+
+       * attribute.cs (CheckAttribute, ApplyAttribute): Ensure that we treat operators
+       essentially like methods and apply attributes like MethodImplOptions to them too.
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Perform a check on ec.TypeContainer.TypeBuilder
+       not being null.
+
+       * codegen.cs (EmitContext): The constructor now takes in an extra argument specifying the
+       DeclSpace as the distinction is important. We provide sane defaults as usually the TypeContainer
+       is the DeclSpace.
+
+       * Update code everywhere accordingly.
+
+       * ecore.cs : Change references to ec.TypeContainer to ec.DeclSpace where appropriate.
+
+       * cs-parser.jay (enum_declaration): Set the current namespace of the enum.
+
+2002-02-28  Ravi Pratap  <ravi@ximian.com>
+
+       * rootcontext.cs (LookupType): As we cycle through the chain of namespaces
+       try performing lookups against those instead of jumping straight into using
+       the 'using' clauses.
+
+       (ImplicitParent): Add. Thanks to Felix Arrese-Igor for this idea.
+
+       (LookupType): Perform lookups in implicit parents too.
+
+       * class.cs (GetInterfaceOrClass): Modify to perform the exact same lookup
+       sequence as RootContext.LookupType. 
+
+       * rootcontext.cs (NamespaceLookup): Split out code from LookupType which tries 
+       the various cases of namespace lookups into this method.
+
+2002-03-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Add support for [Attribute ()] (empty arguments
+       in positional arguments)
+
+       * class.cs (Operator): Update the AllowedModifiers to contain
+       extern. 
+
+       * cs-parser.jay: Update operator declaration to allow for the
+       operator body to be empty.
+
+       * cs-tokenizer.cs: Added '\u' unicode support in strings and hex
+       values. 
+
+2002-02-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Method.Emit): Label parameters.
+
+       * driver.cs: Return 1 or 0 as the program exit code.
+
+2002-02-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Special case the `null' object when trying to
+       auto-compute the type, as anything can be explicitly converted to
+       that. 
+
+       * ecore.cs (Expression.ConvertExplicit): Bug fix, thanks for
+       spotting this Paolo.
+
+       (Expression.ImplicitNumericConversion): Perform comparissions of
+       the type using the underlying type in the case of an enumeration
+       rather than using the enumeration type for the compare.
+
+       Cope with the underlying == type case, which is not possible to
+       catch before. 
+
+       (Expression.ConvertNumericExplicit): Perform comparissions of
+       the type using the underlying type in the case of an enumeration
+       rather than using the enumeration type for the compare.
+
+       * driver.cs: If the user does not supply an extension, assume .exe
+
+       * cs-parser.jay (if_statement): Rewrote so that we can track the
+       location for the if statement.
+
+       * expression.cs (Binary.ConstantFold): Only concat strings when
+       the operation is "+", not everything ;-)
+
+       * statement.cs (Statement.EmitBoolExpression): Take a location
+       argument. 
+       (If, While, Do): Track location.
+
+       * expression.cs (Binary.ResolveOperator): In the object + string
+       case, I was missing a call to ConvertImplicit
+
+2002-02-25  Ravi Pratap  <ravi@ximian.com>
+
+       * parameter.cs (Parameter.ExternalType): Take in extra DeclSpace and
+       Location arguments. Ensure we use RootContext.LookupType to do our work
+       and not try to do a direct Type.GetType and ModuleBuilder.GetType
+
+       * interface.cs (PopulateMethod): Handle the type of the parameter being
+       null gracefully.
+
+       * expression.cs (Invocation.BetterFunction): Handle the case when we 
+       have a params method with no fixed arguments and a call is made with no
+       arguments.
+
+2002-02-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: Add support for the quote-escape-sequence in
+       the verbatim-string-literal
+
+       * support.cs (InternalParameters.ParameterModifier): handle null
+       fixed parameters.
+       (InternalParameters.ParameterType): ditto.
+
+       * parameter.cs (VerifyArgs): Also check if the fixed parameter is
+       duplicating the name of the variable parameter.
+       (GetParameterByName): Fix bug where we were not looking up array
+       paramters if they were the only present (thanks Paolo!).
+       (GetParameterInfo): We only have an empty set of types if both
+       fixed and array are set to null.
+       (GetParameterInfo-idx): Handle FixedParameter == null
+
+       * cs-parser.jay: Handle the case where there is no catch
+       statements (missing null test).
+
+2002-02-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs (MainDriver): Be conservative on our command line
+       handling.
+
+       Catch DirectoryNotFoundException when calling GetFiles.
+
+       (SplitPathAndPattern): Used to split the input specification into
+       a path and a pattern that we can feed to Directory.GetFiles.
+
+2002-02-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Fixed): Implement the last case of the Fixed
+       statement (string handling).
+
+       * expression.cs (StringPtr): New class used to return a char * to
+       a string;  Used by the Fixed statement.
+
+       * typemanager.cs: Add char_ptr_type.  Add get_OffsetToStringData method.
+
+       * expression.cs (Binary.ResolveOperator): Remove redundant
+       MemberLookup pn parent type.
+       Optimize union call, we do not need a union if the types are the same.
+       (Unary.ResolveOperator): REmove redundant MemberLookup on parent
+       type.
+
+       Specialize the use of MemberLookup everywhere, instead of using
+       the default settings. 
+
+       (StackAlloc): Implement stackalloc keyword.
+
+       * cs-parser.jay: Add rule to parse stackalloc.
+
+       * driver.cs: Handle /h, /help, /?
+
+       * expression.cs (MakeByteBlob): Removed the hacks we had in place
+       before we supported unsafe code.
+
+       * makefile: add --unsafe to the self compilation of mcs.
+
+2002-02-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (PointerArithmetic): New class that is used to
+       perform pointer arithmetic.
+       (Binary.Resolve): Handle pointer arithmetic
+       Handle pointer comparission.
+       (ArrayPtr): Utility expression class that is used to take the
+       address of an array.
+
+       (ElementAccess): Implement array access for pointers
+
+       * statement.cs (Fixed): Implement fixed statement for arrays, we
+       are missing one more case before we are done.
+
+       * expression.cs (Indirection): Implement EmitAssign and set the
+       ExprClass to Variable.  This allows pointer dereferences to be
+       treated as variables, and to have values assigned to them.
+
+       * ecore.cs (Expression.StoreFromPtr): New utility function to
+       store values dereferencing.
+
+2002-02-20  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Binary.ResolveOperator): Ensure that we are
+       not trying to operate on a void type - this fixes the reported
+       bug.
+
+       * decl.cs (CheckMethodAgainstBase): Do not allow overriding if
+       the parent implementation is sealed.
+
+       * ../errors/cs0239.cs : Add.
+
+       * attribute.cs (ApplyAttributes): Handle Modulebuilders too.
+
+       * typemanager.cs (unverifiable_code_type): Corresponds to 
+       System.Security.UnverifiableCodeAttribute. We need to emit this for modules
+       which have unsafe code in them.
+
+       * rootcontext.cs (EmitCode): Emit the above attribute when we are in an 
+       unsafe context.
+
+2002-02-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: Add support for @"litreal strings"
+
+       Make tokenizer accept pre-processor directives
+       on any column (remove the old C-like limitation). 
+
+       * rootcontext.cs (EmitCode): Emit any global attributes.
+       (AddGlobalAttributes): Used to keep track of assembly attributes. 
+
+       * attribute.cs (ApplyAttributes): Support AssemblyAttributes.
+
+       * cs-parser.jay: Add support for global attributes.  
+
+2002-02-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Indirection): New helper class.  Unary will
+       create Indirection classes to be able to implement the
+       IMemoryLocation interface on it.
+
+2002-02-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay (fixed_statement): reference the right statement.
+
+       * statement.cs (Fixed.Emit): Finish implementing the fixed
+       statement for the &x case.
+
+2002-02-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Property.Define, Method.Define): Remove newslot when
+       `implementing'.  
+
+       * modifiers.cs: My use of NewSlot when `Abstract' was set was
+       wrong.  NewSlot should only be used if the `new' keyword is present.
+
+       * driver.cs (GetSystemDir): Use CodeBase instead of FullName for
+       locating our system dir.  Sorry about this.
+
+2002-02-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs (GetSystemDir): Compute correctly the location of our
+       system assemblies.  I was using the compiler directory instead of
+       the library directory.
+
+2002-02-13  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (BetterFunction): Put back in what Miguel commented out
+       since it is the correct fix. The problem is elsewhere ;-)
+
+       (IsParamsMethodApplicable): Fix bug where we were not checking that the fixed
+       parameters of the parms method are themselves compatible or not !
+
+       (StandardConversionExists): Fix very dangerous bug where we were forgetting
+       to check that a class implements an interface before saying that an implicit
+       conversion was allowed. Use ImplementsInterface to do the checking.
+
+2002-02-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Method.Define): Track whether we are an explicit
+       implementation or not.  And only call DefineMethodOverride if we
+       are an explicit implementation.
+
+       (Property.DefineMethod): Ditto.
+
+2002-02-11  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (BetterFunction): Catch hideous bug which was
+        preventing us from detecting ambiguous calls due to implicit casts i.e
+       cs0121.
+
+2002-01-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * support.cs (Pair): Remove un-needed method.  I figured why I was
+       getting the error in cs-parser.jay, the variable in a foreach loop
+       is readonly, and the compiler does not really treat this as a variable.
+
+       * cs-parser.jay (fixed_statement): Fix grammar.  Use ASSIGN
+       instead of EQUALS in grammar.  
+
+       * typemanager.cs (VerifyUnmanaged): Report correct error (208)
+
+       * expression.cs (Unary.DoResolve): Check whether the argument is
+       managed or not.
+
+2002-01-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * support.cs: Api for Pair to set a value.  Despite the fact that
+       the variables are public the MS C# compiler refuses to compile
+       code that accesses the field if the variable is part of a foreach
+       statement. 
+
+       * statement.cs (Fixed): Begin implementation of the fixed
+       statement.
+
+       (Block.AddVariable): Return the VariableInfo on success and null
+       on failure instead of true/false. 
+
+       * cs-parser.jay (foreach): Catch errors on variables already
+       defined (we were ignoring this value before) and properly unwind
+       the block hierarchy
+
+       (fixed_statement): grammar for the fixed statement.
+
+2002-01-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (UnaryMutator.IsIncrementableNumber): Allow also
+       pointer types to be incretemented.
+
+       (SizeOf): Implement.
+
+       * cs-parser.jay (pointer_member_access): Implement
+       expr->IDENTIFIER production.
+
+       * expression.cs (IndexerAccess.DoResolve, ArrayAccess.DoResolve,
+       MemberAccess.DoResolve, Invocation.DoResolve): Check for pointers
+       on safe contexts.
+
+       (Unary): Implement indirection.
+
+       * ecore.cs (Expression.UnsafeError): Reports error 214 (pointer
+       use in non-unsafe context).
+
+       (SimpleName.DoResolve): Check for pointers in field access on safe
+       contexts. 
+
+       (Expression.LoadFromPtr): Factor the load-indirect code in this
+       function.  This was duplicated in UnboxCast and ParameterReference
+
+2002-01-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ComposedCast): report an error if a pointer cast
+       is used in a safe region.
+
+       * ecore.cs (Expression.ConvertExplicit): Add rules for implicit
+       pointer type casts in unsafe context.
+
+       * codegen.cs (EmitContext): Set up IsUnsafe.
+
+       * cs-parser.jay (non_expression_type): Add productions for pointer
+       casts. 
+
+       * expression.cs (Invocation.EmitCall): Remove chunk of buggy
+       code.  We should not use force into static mode if the method is
+       not virtual.  Fixes bug in MIS
+
+       * statement.cs (Do.Emit, While.Emit, For.Emit,
+       Statement.EmitBoolExpression): Add support to Do and While to
+       propagate infinite loop as `I do return' semantics.
+
+       Improve the For case to also test for boolean constants.
+
+       * attribute.cs (Attribute.ApplyAttributes): Add ParameterBuilder
+       to the list of attributes we can add.
+
+       Remove `EmitContext' argument.
+
+       * class.cs (Method.Define): Apply parameter attributes.
+       (Constructor.Define): Apply parameter attributes.
+       (MethodCore.LabelParameters): Move here the core of labeling
+       parameters. 
+
+       * support.cs (ReflectionParameters.ParameterModifier,
+       InternalParameters.ParameterModifier): Use IsByRef on the type and
+       only return the OUT bit for these parameters instead of in/out/ref
+       flags.
+
+       This is because I miss-understood things.  The ParameterInfo.IsIn
+       and IsOut represent whether the parameter has the [In] and [Out]
+       attributes set.  
+
+2002-01-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (FieldExpr.Emit): Release temporaries.
+
+       * assign.cs (LocalTemporary.Release): new function.
+
+       * codegen.cs (EmitContext.GetTemporaryStorage,
+       EmitContext.FreeTemporaryStorage): Rework the way we deal with
+       temporary storage.  Now we can "put back" localbuilders when we
+       are done with them
+
+2002-01-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (FieldExpr.Emit): Handle initonly fields specially: we
+       need to make a copy of the variable to generate verifiable code.
+
+2002-01-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Compute dynamically the system directory.
+
+       * ecore.cs (CopyNewMethods): reworked, exposed, made public.
+       Slower, but more generally useful.  Used by the abstract
+       registering implementation. 
+
+       * expression.cs (ResolveMemberAccess): Reorder the way we evaluate
+       the rules for the special rule on Type/instances.  First check if
+       we have the same name, and if so, try that special static path
+       rather than the instance path.
+
+2002-01-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Emit 642 (warning: possible empty statement) for
+       for, while and if.
+
+       * class.cs (TypeBuilder.DefineType): Do not allow inheritance from
+       Enum, ValueType, Delegate or Array for non-corlib compiles.
+
+       * cs-tokenizer.cs: Catch long identifiers (645)
+
+       * typemanager.cs (IndexerPropetyName): Ravi never tested this
+       piece of code.
+
+       * class.cs (TypeContainer.RegisterRequiredImplementations): Bug
+       fix, we were returning too early, so we were not registering
+       pending methods from abstract classes.
+
+       Do not register pending methods if the class is abstract.
+
+       * expression.cs (Conditional.DoResolve): Report circular implicit
+       conversions when we neecd to compute it for conditional
+       expressions. 
+
+       (Is.DoResolve): If the expression is always of the provided type,
+       flag warning 183.  If the expression can not ever be of the
+       provided type flag warning 184.
+
+       * class.cs: Catch 169 as well.
+
+       * ecore.cs (FieldExpr): For now in AddressOf mark as assigned and
+       read. 
+
+2002-01-18  Nick Drochak  <ndrochak@gol.com>
+
+       * makefile: remove path to beta2 csc.exe.  path to csc.exe must be in PATH instead.
+
+2002-01-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * interface.cs: (PopulateMethod): Check for pointers being defined
+       only if the unsafe context is active.
+       (PopulateProperty): ditto.
+       (PopulateIndexer): ditto.
+
+       * class.cs (Method, Method.Define): Allow `unsafe' modifier to be
+       specified.  If pointers are present, make sure that they are
+       present in an unsafe context.
+       (Constructor, Constructor.Define): ditto.
+       (Field, Field.Define): ditto.
+       (Property, Property.Define): ditto.
+       (Event, Event.Define): ditto.
+
+       * interface.cs (Interface.GetInterfaceTypeByName): Only lookup the
+       hashtable if there are classes or structs defined.
+
+       * expression.cs (LocalVariableReference.DoResolve): Simplify this
+       code, as the constant resolution moved.
+
+       * statement.cs (Block.EmitMeta): Resolve all constants as we emit
+       the metadata, so we can flag error 133. 
+
+       * decl.cs (MemberCore.UnsafeOK): New function to test that a
+       pointer is being declared in an unsafe context.
+
+2002-01-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * modifiers.cs (Modifiers.Check): Require a Location argument.
+       Report error 227 for Unsafe use.
+
+       * typemanager.cs: Remove IsPointerType, we should be using Type.IsPointer
+
+       * statement.cs (For.Emit): If the test is null, then report that
+       we do `return', as we wont reach anything afterwards.
+
+       (Switch.SwitchGoverningType): Track the expression that matched
+       the conversion.
+
+       * driver.cs: Allow negative numbers as an error code to flag.
+
+       * cs-parser.jay: Handle 1551.
+
+       * namespace.cs: Add 1537 checking (repeated using alias namespaces).
+
+2002-01-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Report 1518 (type declaration can only contain
+       class, struct, interface, enum or delegate)
+
+       (switch_label): Report 1523 (keywords `case' or `default' must
+       preced code)
+
+       (opt_switch_sections): Report 1522 (empty switch)
+
+       * driver.cs: Report 1515 (response file specified multiple times)
+       Report 1516 (Source file specified multiple times).
+
+       * expression.cs (Argument.Resolve): Signal 1510
+
+       (BaseAccess.Resolve, BaseIndexer.Resolve): Signal 1511 (base
+       access not allowed in static code)
+
+2002-01-11  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (IsPointerType): Utility method which we are going
+       to need a lot.
+
+       * ecore.cs (ImplicitReferenceConversion): A pointer type cannot be cast to
+       the object type, so we take care of that.
+
+       * expression.cs (FullMethodDesc): Also include the return type in descriptions.
+
+       * support.cs (ParameterDesc): Fix minor bug which was causing params tags to be
+       added to non-params parameters :-)
+
+       * typemanager.cs (CSharpName): Include 'void' type too. 
+
+       (void_ptr_type): Include in the set of core types.
+
+       * ecore.cs (ConvertImplicit): Make use of ConvertImplicitStandard instead of 
+       duplicating code.
+
+       (ConvertImplicitStandard): Handle standard implicit pointer conversions when we have 
+       an unsafe context.
+
+       * cs-parser.jay (local_variable_pointer_type): Add support for 'void *' as I had 
+       completely forgotten about it.
+
+2002-01-10  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (pointer_type): Add. This begins our implementation
+       of parsing rules for unsafe code.
+
+       (unsafe_statement): Implement.
+
+       (embedded_statement): Modify to include the above.
+
+       * statement.cs (Unsafe): Implement new class for unsafe blocks.
+
+       * codegen.cs (EmitContext.InUnsafe): Add. This determines
+       if the current context is an unsafe one.
+
+       * cs-parser.jay (local_variable_pointer_type): Since local variable types
+       are handled differently, we need separate rules for them.
+
+       (local_variable_declaration): Update to use local_variable_pointer_type
+       to allow variable declarations of unmanaged pointer types.
+
+       * expression.cs (Unary.ResolveOperator): Ensure that the '&' operator is used only
+       in unsafe contexts.
+
+       * ../errors/cs0214.cs : Add.
+
+2002-01-16  Nick Drochak  <ndrochak@gol.com>
+
+       * makefile: remove 'response' file when cleaning.
+
+2002-01-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Report 1524.
+
+2002-01-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (RegisterMethod): drop checking if we have
+       registered this from here
+
+2002-01-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Method.EmitDestructor): Implement calling our base
+       destructor. 
+
+       * statement.cs (Try.Emit): Fix to reset the InFinally to the old
+       value of InFinally.
+
+       * codegen.cs (EmitContext.EmitTopBlock): Destructors will call
+       this routine and will wrap the call in a try/catch block.  Deal
+       with the case.
+
+2002-01-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (Expression.MemberLookup): instead of taking a
+       parameter `same_type' that was used to tell whether we could
+       access private members we compute our containing type from the
+       EmitContext.
+
+       (FieldExpr): Added partial support for volatile fields.  This does
+       not work for volatile fields exposed from assemblies, as I can not
+       figure out how to extract the modreq from it.
+
+       Updated all the source files to use this.
+
+       * codegen.cs (EmitContext): Compute ContainerType ahead of time,
+       because it is referenced by MemberLookup very often. 
+
+2002-01-09  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (IndexerPropertyName): If we have a TypeBuilder, use
+       TypeBuilder.GetCustomAttributes to retrieve what we need.
+
+       Get rid of redundant default_member_attr_type as this is the same as
+       default_member_type which already exists.
+
+       * interface.cs, attribute.cs : Update accordingly.
+
+2002-01-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs: Enable IndexerPropertyName again.  It does not
+       work for TYpeBuilders though.  Ravi, can you please fix this?
+
+       * cs-tokenizer.cs: Accept _ as a name in pp-expressions.
+
+       * expression.cs (Argument.Emit): Handle the case of ref objects
+       being passed to ref functions;  
+
+       (ParameterReference.EmitLoad): Loads the content of the pointer
+       without dereferencing.
+
+2002-01-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: Implemented the pre-processing expressions.
+
+2002-01-08  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Indexer.DefineMethod): Incorporate the interface
+       type in the name of the method if we are doing explicit interface
+       implementation.
+
+       * expression.cs (ConversionExists): Remove as it is completely obsolete.
+
+       (BetterConversion): Fix extremely trivial bug where we were referring to
+       ConversionExists instead of StandardConversionExists ! Hooray, things are fine
+       again !
+
+       * ../errors/bug16.cs : Add although we have fixed it.
+
+2002-01-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (BaseIndexer): Begin implementation.
+
+       * class.cs (TypeContainer.IsInterfaceMethod): Bug fix.
+
+       * cs-parser.jay (indexer_declarator): Use qualified_identifier
+       production directly to remove a shift/reduce, and implement
+       explicit interface implementation.
+
+       * cs-tokenizer.cs: Fix tokenizer, it was consuming one extra char
+       after a floating point suffix.
+
+       * expression.cs (DoNumericPromotions): Improved the conversion for
+       uint/uint.  If we have a constant, we avoid doing a typecast to a
+       larger type.
+
+       * class.cs (Indexer): Implement explicit interface implementation
+       for indexers.
+
+Sat Jan 5 16:08:23 CET 2002 Paolo Molaro <lupus@ximian.com>
+
+       * class.cs: make the default instance constructor public and hidebysig.
+
+2001-01-03  Ravi Pratap  <ravi@ximian.com>
+
+       * interface.cs (EmitDefaultMemberAttr): Make this helper method static
+       so we can call it from elsewhere.
+
+       * class.cs (TypeContainer.Emit): Emit the attribute here too. The rule is that
+       we emit it internally if the class has a defined indexer; otherwise the user
+       emits it by decorating the class definition with the DefaultMemberAttribute.
+
+       * attribute.cs (ApplyAttributes): Perform checks to see that the DefaultMember
+       attribute is not used on a type which defines an indexer.
+
+       * cs-tokenizer.cs (get_cmd_arg): Ensure we trim whitespace and also include the tab
+       character when we skip whitespace.
+
+       * ../errors/cs0646.cs : Add.
+
+2002-01-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (SimpleName.ResolveSimpleName): Report error 120
+       again. 
+
+       * makefile: Add practical target `mcs3.exe' which builds the third
+       generation compiler. 
+
+       * expression.cs (New): Fix structures constructor calling.
+
+       * class.cs (Property, Method, Indexer): Emit Final flag on the
+       method if we are an interface implementation and we are not
+       abstract. 
+
+       * ecore.cs (PropertyExpr): New public field `IsBase', tells
+       whether this property is referencing a `base' method.
+
+       * expression.cs (Invocation.EmitCall): take an extra argument:
+       is_base, this is used to determine whether the `call' or
+       `callvirt' opcode should be used.
+
+
+       * delegate.cs: update EmitCall.
+
+       * class.cs (Method.Define): Set NewSlot for the cases where we are
+       not implementing an interface method.
+
+       (Property.Define): ditto.
+
+2002-01-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: (Tokenizer.escape): Escape '\r' as '\r' not as
+       'r'.  Allows mcs to parse itself fully.
+
+2002-01-02  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ArrayCreation.num_automatic_initializers): Keep track
+       of the number of initializers that require the InitializeArray method.
+
+       (CheckIndices): Store the Expression in all cases - not the plain value. Also
+       update the above field where necessary.
+
+       (MakeByteBlob): Update accordingly.
+
+       (DoEmit): Call EmitStaticInitializers only if the number of initializers is 
+       greater than 2.
+
+       (EmitDynamicInitializers): Update in accordance with the new optimization.
+
+       (ArrayAccess.EmitStoreOpcode): Include char type along with short and ushort - the
+       same OpCode applies.
+
+       * cs-parser.jay : Fix some glaring errors I introduced.
+
+2002-01-01  Ravi Pratap  <ravi@ximian.com> 
+
+       * parameters.cs (AddVariable, AddConstant): Pass in current_local_parameters
+       so that we can check for name clashes there too.
+
+       * typemanager.cs (default_member_attr_type): The attribute that we need to emit
+       for interface indexers.
+
+       * interfaces.cs (Define): Emit the default member attribute.
+
+       * expression.cs (MakeByteBlob): Fix extremely trivial bug where the wrong
+       variable was being referred to while setting the value ;-)
+
+2002-01-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (MakeByteBlob): Optimize: we do not need to fill
+       byte-by-byte information when we know the data is zero.
+
+       Make the block always a multiple of 4, because
+       DefineInitializedData has a bug.
+
+       * assign.cs: Fix, we should assign from the temporary, not from
+       the source. 
+
+       * expression.cs (MakeByteBlob): Fix my incorrect code.
+
+2001-12-31  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (EnumToUnderlying): This function is used to get
+       the underlying type from an enumeration, because it does not
+       always work. 
+
+       * constant.cs: Use the I4_S form for values between -128 and 127.
+
+       * statement.cs (Block.LookupLabel): Looks up a label.
+       (Block): Drop support for labeled blocks.
+
+       (LabeledStatement): New kind of statement that represents a label
+       only.
+
+       (Goto): Finally implement this bad boy.
+
+       * cs-parser.jay: Update to reflect new mechanism to implement
+       labels.
+
+2001-12-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs (EmitContext.This): a codegen property that keeps the
+       a single instance of this instead of creating many different this
+       instances. 
+
+       * delegate.cs (Delegate.DoResolve): Update to use the property;
+
+       * ecore.cs (SimpleName.SimpleNameResolve): Ditto
+
+       * expression.cs (BaseAccess.DoResolve): Ditto.
+
+2001-12-29  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (methodimpl_attr_type): Add to hold the type
+       corresponding to System.Runtime.CompilerServices.MethodImplAttribute.
+
+       (InitCoreTypes): Update accordingly.
+
+       * attribute.cs (Resolve): Remember if the attribute is a MethodImplAttribute
+       so we can quickly store the state.
+
+       (ApplyAttributes): Set the correct implementation flags
+       for InternalCall methods.
+
+2001-12-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (EmitCall): if a method is not virtual, then do
+       not use callvirt on it.
+
+       (ArrayAccess.EmitAssign): storing non-builtin value types (ie,
+       user defined stuff) requires the use of stobj, which takes an
+       address on the stack instead of an array and an index.  So emit
+       the Ldelema operation for it.
+
+       (EmitStoreOpcode): Use stobj for valuetypes.
+
+       (UnaryMutator.EmitCode): Use the right 1 value depending on
+       whether we are dealing with int64/uint64, float or doubles.
+
+       * class.cs (TypeContainer.AddConstructor): Fix the logic to define
+       constructors that I implemented last night.
+
+       (Constructor.IsDefault): Fix to work properly for static
+       constructors.
+
+       * cs-parser.jay (CheckDef): report method signature errors.
+       Update error number 103 to be 132.
+
+       * decl.cs: New AdditionResult enumeration value: MethodExists.
+       Although we do this check for methods later on in the semantic
+       analysis, catching repeated default constructors is so easy that
+       we catch these here. 
+
+       * expression.cs (Binary.DoNumericPromotions): Fix the uint64 type
+       promotions code.
+
+       (ParameterReference.EmitAssign, Emit): handle
+       bools as bytes.
+
+       (ArrayAccess.EmitLoadOpcode): Handle bool type here.
+       (ArrayAccess.EmitStoreOpcode): ditto.
+
+       * cs-tokenizer.cs (is_punct): Eliminated empty computation.
+
+       * expression.cs (MakeByteBlob): Complete all the missing types
+       (uint, short, ushort, byte, sbyte)
+
+       * class.cs: Only init instance field initializers on instance
+       constructors. 
+
+       Rename `constructors' to instance_constructors. 
+
+       (TypeContainer.AddConstructor): Only add constructors to the list
+       if it is not static.
+
+       Make sure that we handle default_static_constructor independently
+       everywhere where we handle instance_constructors
+
+2001-12-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs: Do not lookup or create a base initializer for a
+       static constructor.
+
+       (ConstructorInitializer.Resolve): use the proper type to lookup
+       for constructors.
+
+       * cs-parser.jay: Report error 1585 (modifiers between type and name).
+
+       * enum.cs, interface.cs: Remove CloseType, this is taken care by
+       in DeclSpace. 
+
+       * decl.cs: CloseType is now an virtual method, the default
+       implementation just closes this type.
+
+2001-12-28  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (DefinePInvokeMethod): Set the implementation flags
+       to PreserveSig by default. Also emit HideBySig on such methods.
+
+       Basically, set the defaults to standard values.
+
+       * expression.cs (Invocation.BetterFunction): We need to make sure that for each
+       argument, if candidate is better, it can't be worse than the best !
+
+       (Invocation): Re-write bits to differentiate between methods being
+       applicable in their expanded form and their normal form - for params
+       methods of course.
+
+       Get rid of use_standard everywhere as only standard conversions are allowed
+       in overload resolution. 
+
+       More spec conformance.
+
+2001-12-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Add --timestamp, to see where the compiler spends
+       most of its time.
+
+       * ecore.cs (SimpleName.DoResolve): Do not create an implicit
+       `this' in static code.
+
+       (SimpleName.DoResolve): Implement in terms of a helper function
+       that allows static-references to be passed upstream to
+       MemberAccess.
+
+       (Expression.ResolveWithSimpleName): Resolve specially simple
+       names when called by MemberAccess to implement the special
+       semantics. 
+
+       (Expression.ImplicitReferenceConversion): Handle conversions from
+       Null to reference types before others, as Null's type is
+       System.Object. 
+
+       * expression.cs (Invocation.EmitCall): Handle the special case of
+       calling methods declared on a reference type from a ValueType
+       (Base classes System.Object and System.Enum)
+
+       (MemberAccess.Resolve): Only perform lookups on Enumerations if
+       the left hand side is a TypeExpr, not on every enumeration. 
+
+       (Binary.Resolve): If types are reference types, then do a cast to
+       object on operators != and == of both arguments.
+
+       * typemanager.cs (FindMembers): Extract instance and static
+       members if requested.
+
+       * interface.cs (PopulateProperty): Use void_type instead of null
+       as the return type for the setter method.
+
+       (PopulateIndexer): ditto.
+
+2001-12-27  Ravi Pratap  <ravi@ximian.com>
+
+       * support.cs (ReflectionParameters): Fix minor bug where we
+       were examining the wrong parameter for the ParamArray attribute.
+
+       Cope with requests for the type of the parameter at position
+       greater than the params parameter's. We now return the element
+       type of the params array as that makes more sense.
+
+       * expression.cs (Invocation.IsParamsMethodApplicable): Update 
+       accordingly as we no longer have to extract the element type
+       ourselves.
+
+       (Invocation.OverloadResolve): Update.
+
+2001-12-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Foreach.GetEnumeratorFilter): Do not compare
+       against IEnumerator, test whether the return value is a descendant
+       of the IEnumerator interface.
+
+       * class.cs (Indexer.Define): Use an auxiliary method to implement
+       the other bits of the method definition.  Begin support for
+       explicit interface implementation.
+
+       (Property.DefineMethod): Use TypeManager.void_type instead of null
+       for an empty return value.
+
+2001-12-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (MemberAccess.ResolveMemberAccess): if we are
+       dealing with a FieldExpr which is composed of a FieldBuilder, in
+       the code path we did extract the constant, but we should have
+       obtained the underlying value to be able to cast it (otherwise we
+       end up in an infinite loop, this is what Ravi was running into).
+
+       (ArrayCreation.UpdateIndices): Arrays might be empty.
+
+       (MemberAccess.ResolveMemberAccess): Add support for section
+       14.5.4.1 that deals with the special case of E.I when E is a type
+       and something else, that I can be a reference to a static member.
+
+       (ArrayCreation.MakeByteBlob): It is not an error to not be able to
+       handle a particular array type to create byte blobs, it is just
+       something we dont generate byteblobs for.
+
+       * cs-tokenizer.cs (get_cmd_arg): Ignore \r in commands and
+       arguments. 
+
+       * location.cs (Push): remove the key from the hashtable that we
+       are about to add.   This happens for empty files.
+
+       * driver.cs: Dispose files after we have parsed them.
+
+       (tokenize): new function that only runs the tokenizer on its
+       input, for speed testing.
+
+2001-12-26  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Event.Define): Define the private field only if there
+       are no accessors defined.
+
+       * expression.cs (ResolveMemberAccess): If there is no associated
+       field with the event, that means we have an event defined with its
+       own accessors and we should flag error cs0070 since transforming
+       ourselves into a field is not valid in that case.
+
+       * ecore.cs (SimpleName.DoResolve): Same as above.
+
+       * attribute.cs (DefinePInvokeMethod): Set the default calling convention
+       and charset to sane values.
+
+2001-12-25  Ravi Pratap  <ravi@ximian.com>
+
+       * assign.cs (DoResolve): Perform check on events only if they 
+       are being accessed outside the declaring type.
+
+       * cs-parser.jay (event_declarations): Update rules to correctly
+       set the type of the implicit parameter etc.
+
+       (add_accessor, remove_accessor): Set current local parameters.
+
+       * expression.cs (Binary): For delegate addition and subtraction,
+       cast the return value from the method into the appropriate delegate
+       type.
+
+2001-12-24  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (RegisterDelegateData, GetDelegateData): Get rid
+       of these as the workaround is unnecessary.
+
+       * delegate.cs (NewDelegate.DoResolve): Get rid of bits which registered
+       delegate data - none of that is needed at all.
+
+       Re-write bits to extract the instance expression and the delegate method
+       correctly.
+
+       * expression.cs (Binary.ResolveOperator): Handle the '-' binary operator 
+       on delegates too.
+
+       * attribute.cs (ApplyAttributes): New method to take care of common tasks
+       of attaching attributes instead of duplicating code everywhere.
+
+       * everywhere : Update code to do attribute emission using the above method.
+
+2001-12-23  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (IsParamsMethodApplicable): if there are not
+       parameters, return immediately.
+
+       * ecore.cs: The 0 literal can be implicity converted to an enum
+       type. 
+
+       (SimpleName.DoResolve): First lookup the type, then lookup the
+       members. 
+
+       (FieldExpr.Emit): If the InstanceExpression is a ValueType, we
+       want to get its address.  If the InstanceExpression is not
+       addressable, store the result in a temporary variable, then get
+       the address of it.
+
+       * codegen.cs: Only display 219 errors on warning level or above. 
+
+       * expression.cs (ArrayAccess): Make it implement the
+       IMemoryLocation interface.
+
+       (Binary.DoResolve): handle the operator == (object a, object b)
+       and operator != (object a, object b) without incurring into a
+       BoxedCast (because 5 != o should never be performed).
+
+       Handle binary enumerator operators.
+
+       (EmitLoadOpcode): Use Ldelema if the object we are loading is a
+       value type, otherwise use Ldelem_ref.
+
+       Use precomputed names;
+
+       (AddressOf): Implement address of
+
+       * cs-parser.jay (labeled_statement): Fix recursive block
+       addition by reworking the production.
+
+       * expression.cs (New.DoEmit): New has a special case:
+               
+                If we are dealing with a ValueType, we have a few
+                situations to deal with:
+               
+                   * The target of New is a ValueType variable, that is
+                     easy, we just pass this as the variable reference
+               
+                   * The target of New is being passed as an argument,
+                     to a boxing operation or a function that takes a
+                     ValueType.
+               
+                     In this case, we need to create a temporary variable
+                     that is the argument of New.
+
+
+2001-12-23  Ravi Pratap  <ravi@ximian.com>
+
+       * rootcontext.cs (LookupType): Check that current_type is not null before
+       going about looking at nested types.
+
+       * ecore.cs (EventExpr.EmitAddOrRemove): Rename from EmitAssign as we do
+       not implement the IAssignMethod interface any more.
+
+       * expression.cs (MemberAccess.ResolveMemberAccess): Handle EventExprs specially
+       where we tranform them into FieldExprs if they are being resolved from within
+       the declaring type.
+
+       * ecore.cs (SimpleName.DoResolve): Do the same here.
+
+       * assign.cs (DoResolve, Emit): Clean up code considerably. 
+
+       * ../errors/bug10.cs : Add.
+
+       * ../errors/cs0070.cs : Add.
+
+       * typemanager.cs : Use PtrHashtable for Delegate data hashtable etc.
+
+       * assign.cs : Get rid of EventIsLocal everywhere.
+
+2001-12-23  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (ConvertIntLiteral): finished the implementation.
+
+       * statement.cs (SwitchLabel): Convert the value we are using as a
+       key before looking up the table.
+
+2001-12-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs (EmitTopBlock): Require a Location argument now.
+
+       * cs-parser.jay (constructor_declarator): We need to setup
+       current_local_parameters before we parse the
+       opt_constructor_initializer, to allow the variables to be bound
+       to the constructor arguments.
+
+       * rootcontext.cs (LookupType): First lookup nested classes in our
+       class and our parents before we go looking outside our class.
+
+       * expression.cs (ConstantFold): Extract/debox the values at the
+       beginnning. 
+
+       * rootcontext.cs (EmitCode): Resolve the constants first before we
+       resolve the types.  This is not really needed, but it helps debugging.
+
+       * statement.cs: report location.
+
+       * cs-parser.jay: pass location to throw statement.
+
+       * driver.cs: Small bug fix.
+
+       * report.cs: Updated format to be 4-zero filled digits.
+
+2001-12-22  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (CheckIndices): Fix minor bug where the wrong
+       variable was being referred to ;-)
+
+       (DoEmit): Do not call EmitStaticInitializers when the 
+       underlying type is System.Object.
+
+2001-12-21  Ravi Pratap  <ravi@ximian.com>
+
+       * ecore.cs (EventExpr.Resolve): Implement to correctly set the type
+       and do the usual workaround for SRE.
+
+       * class.cs (MyEventBuilder.EventType): New member to get at the type
+       of the event, quickly.
+
+       * expression.cs (Binary.ResolveOperator): Handle delegate addition.
+
+       * assign.cs (Assign.DoResolve): Handle the case when the target
+       is an EventExpr and perform the necessary checks.
+
+       * ecore.cs (EventExpr.EmitAssign): Implement the IAssignMethod
+       interface.
+
+       (SimpleName.MemberStaticCheck): Include check for EventExpr.
+
+       (EventExpr): Set the type in the constructor itself since we 
+       are meant to be born fully resolved.
+
+       (EventExpr.Define): Revert code I wrote earlier.
+               
+       * delegate.cs (NewDelegate.Resolve): Handle the case when the MethodGroup's
+       instance expression is null. The instance expression is a This in that case
+       or a null, depending on whether it is a static method or not.
+
+       Also flag an error if the reference to a method is ambiguous i.e the MethodGroupExpr
+       refers to more than one method.
+
+       * assign.cs (DoResolve): Check whether the event belongs to the same Type container
+       and accordingly flag errors.
+
+2001-12-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Throw.Emit): Add support for re-throwing exceptions.
+
+2001-12-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * location.cs (ToString): Provide useful rutine.
+
+2001-12-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (Expression.ConvertIntLiteral): Do not return Constant
+       objects, return the actual integral boxed.
+
+       * statement.cs (SwitchLabel): define an ILLabel for each
+       SwitchLabel. 
+
+       (Switch.CheckSwitch): If the value is a Literal, extract
+       the underlying literal.
+
+       Also in the unused hashtable we had, add the SwitchLabel so we can
+       quickly look this value up.
+
+       * constant.cs: Implement a bunch of new constants.  Rewrite
+       Literal based on this.  Made changes everywhere to adapt to this.
+
+       * expression.cs (Expression.MakeByteBlob): Optimize routine by
+       dereferencing array only once, and also copes with enumrations.
+
+       bytes are two bytes wide, not one.
+
+       (Cast): Perform constant conversions.
+
+       * ecore.cs (TryImplicitIntConversion): Return literals instead of
+       wrappers to the literals here.
+
+       * expression.cs (DoNumericPromotions): long literals can converted
+       to ulong implicity (this is taken care of elsewhere, but I was
+       missing this spot).
+
+       * ecore.cs (Expression.Literalize): Make the return type Literal,
+       to improve type checking.
+
+       * rootcontext.cs: Lookup for nested classes in our class hierarchy.
+
+2001-12-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * literal.cs: Revert code from ravi that checked the bounds.  The
+       bounds are sane by the definition of the type itself. 
+
+       * typemanager.cs: Fix implementation of ImplementsInterface.  We
+       need to actually look up in our parent hierarchy for interfaces
+       implemented. 
+
+       * const.cs: Use the underlying type for enumerations
+
+       * delegate.cs: Compute the basename for the delegate creation,
+       that should fix the delegate test case, and restore the correct
+       Type Lookup semantics in rootcontext
+
+       * rootcontext.cs: Revert Ravi's last patch.  The correct way of
+       referencing a nested type with the Reflection API is using the "+"
+       sign. 
+
+       * cs-parser.jay: Do not require EOF token at the end.
+
+2001-12-20  Ravi Pratap  <ravi@ximian.com>
+
+       * rootcontext.cs (LookupType): Concatenate type names with
+       a '.' instead of a '+' The test suite passes again.
+
+       * enum.cs (Enum.DefineEnum): Set RTSpecialName on the 'value__'
+       field of the enumeration.
+
+       * expression.cs (MemberAccess.ResolveMemberAccess): Add support for
+       the case when the member is an EventExpr.
+
+       * ecore.cs (EventExpr.InstanceExpression): Every event which is not
+       static has an associated instance expression.
+
+       * typemanager.cs (RegisterEvent): The usual workaround, now for events.
+
+       (GetAddMethod, GetRemoveMethod): Workarounds, as usual.
+
+       * class.cs (Event.Define): Register event and perform appropriate checks
+       for error #111.
+
+       We define the Add and Remove methods even if the use provides none because
+       in that case, we provide default implementations ourselves.
+
+       Define a private field of the type of the event. This is done by the CSC compiler
+       and we should be doing it too ;-)
+
+       * typemanager.cs (delegate_combine_delegate_delegate, delegate_remove_delegate_delegate):
+       More methods we use in code we generate.
+
+       (multicast_delegate_type, delegate_type): Two separate types since the distinction
+       is important.
+
+       (InitCoreTypes): Update accordingly for the above.
+
+       * class.cs (Event.Emit): Generate code for default accessors that we provide
+
+       (EmitDefaultMethod): Do the job in the above.
+
+       * delegate.cs (DefineDelegate): Use TypeManager.multicast_delegate_type in the 
+       appropriate place.
+
+2001-12-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Indexer.Define): Fix bug, we were setting both Get/Set
+       builders even if we were missing one.
+
+       * interface.cs, class.cs, enum.cs: When calling DefineNestedType
+       pass the Basename as our class name instead of the Name.  The
+       basename will be correctly composed for us.
+
+       * parameter.cs (Paramters): Now takes a Location argument.
+
+       * decl.cs (DeclSpace.LookupType): Removed convenience function and
+       make all the code call directly LookupType in RootContext and take
+       this chance to pass the Location information everywhere.
+
+       * Everywhere: pass Location information.
+
+2001-12-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Constructor.Define): Updated way of detecting the
+       length of the parameters.
+
+       (TypeContainer.DefineType): Use basename as the type name for
+       nested types.
+
+       (TypeContainer.Define): Do not recursively define types here, as
+       definition is taken care in order by the RootContext.
+
+       * tree.cs: Keep track of namespaces in a per-file basis.
+
+       * parameter.cs (Parameter.ComputeSignature): Update to use
+       DeclSpace. 
+
+       (Parameters.GetSignature): ditto.
+
+       * interface.cs (InterfaceMethod.GetSignature): Take a DeclSpace
+       instead of a TypeContainer.
+
+       (Interface.SemanticAnalysis): Use `this' instead of our parent to
+       resolve names.  Because we need to be resolve in our context, not
+       our parents.
+
+       * driver.cs: Implement response files.
+
+       * class.cs (TypeContainer.DefineType): If we are defined, do not
+       redefine ourselves.
+
+       (Event.Emit): Emit the code for add/remove handlers.
+       (Event.Define): Save the MethodBuilders for add/remove.
+
+       * typemanager.cs: Use pair here too.
+
+       * cs-parser.jay: Replaced use of DictionaryEntry for Pair because
+       DictionaryEntry requires the first argument to be non-null.  
+
+       (enum_declaration): Compute full name for registering the
+       enumeration.
+
+       (delegate_declaration): Instead of using
+       formal_parameter_list, use opt_formal_parameter_list as the list
+       can be empty.
+
+       * cs-tokenizer.cs (PropertyParsing): renamed from `properties'
+       (EventParsing): New property that controls whether `add' and
+       `remove' are returned as tokens or identifiers (for events);
+
+2001-12-19  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Event.Define): Revamp use of EventBuilder completely. We now
+       use MyEventBuilder only and let it wrap the real builder for us.
+
+       (MyEventBuilder): Revamp constructor etc.
+
+       Implement all operations that we perform on EventBuilder in precisely the same
+       way here too.
+
+       (FindMembers): Update to use the EventBuilder member.
+
+       (Event.Emit): Update accordingly.
+
+2001-12-18  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (MyEventBuilder.Set*): Chain to the underlying builder
+       by calling the appropriate methods.
+
+       (GetCustomAttributes): Make stubs as they cannot possibly do anything
+       useful.
+
+       (Event.Emit): Use MyEventBuilder everywhere - even to set attributes.
+
+2001-12-17  Ravi Pratap  <ravi@ximian.com>
+
+       * delegate.cs (Delegate.Populate): Check that the return type
+       and various parameters types are indeed accessible.
+
+       * class.cs (Constructor.Define): Same here.
+
+       (Field.Define): Ditto.
+
+       (Event.Define): Ditto.
+
+       (Operator.Define): Check that the underlying Method defined itself
+       correctly - so it's MethodBuilder should not be null.
+
+       * delegate.cs (DelegateInvocation.DoResolve): Bale out if the type of the Instance
+       expression happens to be null.
+
+       * class.cs (MyEventBuilder): Workaround for SRE lameness. Implement various abstract
+       members but as of now we don't seem to be able to do anything really useful with it.
+
+       (FindMembers): Handle events separately by returning the MyEventBuilder of the event,
+       not the EventBuilder.
+
+2001-12-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: Add support for defines.
+       Add support for #if, #elif, #else, #endif
+
+       (eval_var): evaluates a variable.
+       (eval): stubbed for evaluating functions.
+
+       * cs-parser.jay: Pass the defines information
+
+       * driver.cs: Add --define command line option.
+
+       * decl.cs: Move MemberCore here.
+
+       Make it the base class for DeclSpace.  This allows us to catch and
+       report 108 and 109 for everything now.
+
+       * class.cs (TypeContainer.Define): Extract all the members
+       before populating and emit the warning 108 (new keyword required
+       to override) instead of having each member implement this.
+
+       (MemberCore.Define): New abstract method, we will be using this in
+       the warning reporting engine in Populate.
+
+       (Operator.Define): Adjust to new MemberCore protocol. 
+
+       * const.cs (Const): This does not derive from Expression, it is a
+       temporary object we use to create fields, it is a MemberCore. 
+
+       * class.cs (Method.Define): Allow the entry point to be in a
+       specific class.
+
+       * driver.cs: Rewrite the argument handler to clean it up a bit.
+
+       * rootcontext.cs: Made it just an auxiliary namespace feature by
+       making everything static.
+
+       * driver.cs: Adapt code to use RootContext type name instead of
+       instance variable.
+
+       * delegate.cs: Remove RootContext argument.
+
+       * class.cs: (Struct, TypeContainer, Class): Remove RootContext
+       argument. 
+
+       * class.cs (Event.Define): The lookup can fail.
+
+       * cs-tokenizer.cs: Begin implementation of pre-procesor. 
+
+       * expression.cs: Resolve the this instance before invoking the code.
+
+2001-12-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Add a production in element_access that allows
+       the thing to become a "type" reference.  This way we can parse
+       things like "(string [])" as a type.
+
+       Note that this still does not handle the more complex rules of
+       casts. 
+
+
+       * delegate.cs (Delegate.Populate): Register the delegage constructor builder here. 
+
+       * ecore.cs: (CopyNewMethods): new utility function used to
+       assemble the list of methods from running FindMembers.
+
+       (MemberLookup): Rework FindMembers so that 
+
+2001-12-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer): Remove Delegates who fail to be
+       defined.
+
+       * delegate.cs (Populate): Verify that we dont get null return
+       values.   TODO: Check for AsAccessible.
+
+       * cs-parser.jay: Use basename to emit error 574 (destructor should
+       have the same name as container class), not the full name.
+
+       * cs-tokenizer.cs (adjust_int): Fit the integer in the best
+       possible representation.  
+
+       Also implements integer type suffixes U and L.
+
+2001-12-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ArrayCreation.DoResolve): We need to do the
+       argument resolution *always*.
+
+       * decl.cs: Make this hold the namespace.  Hold the root context as
+       well.
+       (LookupType): Move here.
+
+       * enum.cs, class.cs, interface.cs: Adapt to new hierarchy.
+
+       * location.cs (Row, Name): Fixed the code, it was always returning
+       references to the first file.
+
+       * interface.cs: Register properties defined through interfaces.
+
+       * driver.cs: Add support for globbing on the command line
+
+       * class.cs (Field): Make it derive from MemberCore as well.
+       (Event): ditto.
+
+2001-12-15  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Event::Define): Check that the type of the event is a delegate
+       type else flag error #66.
+
+       Also, re-use TypeContainer.MethodModifiersValid here too as the rules are the
+       same.
+
+       * attribute.cs (DefinePInvokeMethod): Handle named arguments and process
+       values of EntryPoint, CharSet etc etc.
+
+       Pass in the values to TypeBuilder.DefinePInvokeMethod; determine Type etc neatly.
+
+       * class.cs (FindMembers): If a method is in transit, its MethodBuilder will
+       be null and we should ignore this. I am not sure if this is really clean. Apparently,
+       there's no way of avoiding hitting this because the call is coming from SimpleName.DoResolve,
+       which needs this to do its work.
+
+       * ../errors/cs0066.cs : Add.
+
+2001-12-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs: (GetPropertyGetter, GetPropertyGetter): New
+       helper functions.
+
+       * class.cs: (MethodSignature.MethodSignature): Removed hack that
+       clears out the parameters field.
+       (MemberSignatureCompare): Cleanup
+
+       (MemberCore): New base class used to share code between MethodCore
+       and Property.
+
+       (RegisterRequiredImplementations) BindingFlags.Public requires
+       either BindingFlags.Instace or Static.  Use instance here.
+
+       (Property): Refactored code to cope better with the full spec.
+
+       * parameter.cs (GetParameterInfo): Return an empty array instead
+       of null on error.
+
+       * class.cs (Property): Abstract or extern properties have no bodies.
+
+       * parameter.cs (GetParameterInfo): return a zero-sized array.
+
+       * class.cs (TypeContainer.MethodModifiersValid): Move all the
+       method modifier validation to the typecontainer so we can reuse
+       this on properties.
+
+       (MethodCore.ParameterTypes): return an empty sized array of types.
+
+       (Property.Define): Test property modifier validity.
+
+       Add tests for sealed/override too.
+
+       (Method.Emit): abstract or extern methods have no bodies.
+
+2001-12-14  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Method.IsPInvoke): Get rid of it as it is an expensive
+       thing.
+
+       (Method::Define, ::Emit): Modify accordingly.
+
+       * expression.cs (Invocation::OverloadResolve): Handle error # 121.
+
+       (ArrayCreation::MakeByteBlob): Handle floats and doubles.
+
+       * makefile: Pass in /unsafe.
+
+2001-12-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (MakeKey): Kill routine.
+
+       * class.cs (TypeContainer.Define): Correctly define explicit
+       method implementations (they require the full interface name plus
+       the method name).
+
+       * typemanager.cs: Deply the PtrHashtable here and stop using the
+       lame keys.  Things work so much better.
+
+       This of course broke everyone who depended on `RegisterMethod' to
+       do the `test for existance' test.  This has to be done elsewhere.
+
+       * support.cs (PtrHashtable): A hashtable that avoid comparing with
+       the object stupid Equals method (because, that like fails all over
+       the place).  We still do not use it.
+
+       * class.cs (TypeContainer.SetRequiredInterface,
+       TypeContainer.RequireMethods): Killed these two routines and moved
+       all the functionality to RegisterRequiredImplementations.
+
+       (TypeContainer.RegisterRequiredImplementations): This routine now
+       registers all the implementations required in an array for the
+       interfaces and abstract methods.  We use an array of structures
+       which can be computed ahead of time to reduce memory usage and we
+       also assume that lookups are cheap as most classes will not
+       implement too many interfaces.
+
+       We also avoid creating too many MethodSignatures.
+
+       (TypeContainer.IsInterfaceMethod): Update and optionally does not
+       clear the "pending" bit if we find that there are problems with
+       the declaration.
+
+       (TypeContainer.VerifyPendingMethods): Update to report errors of
+       methods that look like implementations but are not.
+
+       (TypeContainer.Define): Add support for explicit interface method
+       implementation. 
+
+2001-12-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs: Keep track of the parameters here instead of
+       being a feature of the TypeContainer.
+
+       * class.cs: Drop the registration of parameters here, as
+       InterfaceMethods are also interface declarations.
+
+       * delegate.cs: Register methods with the TypeManager not only with
+       the TypeContainer.  This code was buggy.
+
+       * interface.cs: Full registation here.
+
+2001-12-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Remove reducer for binary expressions, it can not
+       be done this way.
+
+       * const.cs: Put here the code that used to go into constant.cs
+
+       * constant.cs: Put here the code for constants, this is a new base
+       class for Literals.
+
+       * literal.cs: Make Literal derive from Constant.
+
+2001-12-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Return.Emit): Report error 157 if the user
+       attempts to return from a finally block.
+
+       (Return.Emit): Instead of emitting a return, jump to the end of
+       the function.
+
+       * codegen.cs (EmitContext): ReturnValue, ReturnLabel: new
+       LocalBuilder to store the result of the function.  ReturnLabel is
+       the target where we jump.
+
+
+2001-12-09  Radek Doulik  <rodo@ximian.com>
+
+       * cs-parser.jay: remember alias in current namespace
+
+       * ecore.cs (SimpleName::DoResolve): use aliases for types or
+       namespaces
+
+       * class.cs (LookupAlias): lookup alias in my_namespace
+
+       * namespace.cs (UsingAlias): add alias, namespace_or_type pair to
+       aliases hashtable
+       (LookupAlias): lookup alias in this and if needed in parent
+       namespaces
+
+2001-12-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * support.cs: 
+
+       * rootcontext.cs: (ModuleBuilder) Made static, first step into
+       making things static.  I need this to avoid passing the
+       TypeContainer when calling ParameterType.
+
+       * support.cs (InternalParameters.ParameterType): Remove ugly hack
+       that did string manipulation to compute the type and then call
+       GetType.  Use Parameter.ParameterType instead.
+
+       * cs-tokenizer.cs: Consume the suffix for floating values.
+
+       * expression.cs (ParameterReference): figure out whether this is a
+       reference parameter or not.  Kill an extra variable by computing
+       the arg_idx during emission.
+
+       * parameter.cs (Parameters.GetParameterInfo): New overloaded
+       function that returns whether a parameter is an out/ref value or not.
+
+       (Parameter.ParameterType): The type of the parameter (base,
+       without ref/out applied).
+
+       (Parameter.Resolve): Perform resolution here.
+       (Parameter.ExternalType): The full type (with ref/out applied).
+
+       * statement.cs (Using.Emit, Using.EmitExpression): Implement
+       support for expressions on the using statement.
+
+2001-12-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Using.EmitLocalVariableDecls): Split the
+       localvariable handling of the using statement.
+
+       (Block.EmitMeta): Keep track of variable count across blocks.  We
+       were reusing slots on separate branches of blocks.
+
+       (Try.Emit): Emit the general code block, we were not emitting it. 
+
+       Check the type of the declaration to be an IDisposable or
+       something that can be implicity converted to it. 
+
+       Emit conversions if required.
+
+       * ecore.cs (EmptyExpression): New utility class.
+       (Expression.ImplicitConversionExists): New utility function.
+
+2001-12-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Using): Implement.
+
+       * expression.cs (LocalVariableReference): Support read only variables.
+
+       * statement.cs: Remove the explicit emit for the Leave opcode.
+       (VariableInfo): Add a readonly field.
+
+2001-12-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (ConvCast): new class used to encapsulate the various
+       explicit integer conversions that works in both checked and
+       unchecked contexts.
+
+       (Expression.ConvertNumericExplicit): Use new ConvCast class to
+       properly generate the overflow opcodes.
+
+2001-12-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs: The correct type for the EmptyExpression is the
+       element_type, not the variable type.  Ravi pointed this out.
+
+2001-12-04  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Method::Define): Handle PInvoke methods specially
+       by using DefinePInvokeMethod instead of the usual one.
+
+       * attribute.cs (DefinePInvokeMethod): Implement as this is what is called
+       above to do the task of extracting information and defining the method.
+
+2001-12-04  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ArrayCreation::EmitStaticInitializers): Get rid
+       of the condition for string type.
+
+       (Emit): Move that here. 
+
+       (ArrayCreation::CheckIndices): Keep string literals in their expression
+       form.
+
+       (EmitDynamicInitializers): Handle strings appropriately.
+
+2001-12-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs (EmitContext): Replace multiple variables with a
+       single pointer to the current Switch statement.
+
+       * statement.cs (GotoDefault, Switch): Adjust to cleaned up
+       EmitContext.
+
+2001-12-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs 
+
+       * statement.cs (GotoDefault), cs-parser.jay: Implement `goto
+       default'.
+
+       (Foreach.Emit): Foreach on arrays was not setting
+       up the loop variables (for break/continue).
+
+       (GotoCase): Semi-implented.
+
+2001-12-03  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (CheckAttribute): Handle system attributes by using
+       Attribute.GetAttributes to examine information we need.
+
+       (GetValidPlaces): Same here.
+
+       * class.cs (Method::Define): Catch invalid use of extern and abstract together.
+
+       * typemanager.cs (dllimport_type): Core type for System.DllImportAttribute.
+
+       * class.cs (Method.IsPinvoke): Used to determine if we are a PInvoke method.
+
+       (Method::Define): Set appropriate flags if we have a DllImport attribute.
+
+       (Method::Emit): Handle the case when we are a PInvoke method.
+
+2001-12-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Use ResolveWithSimpleName on compound names.
+
+2001-12-02  Ravi Pratap  <ravi@ximian.com>
+
+       * constant.cs (EmitConstant): Make sure we resolve the associated expression
+       before trying to reduce it.
+
+       * typemanager.cs (RegisterConstant, LookupConstant): Implement.
+
+       * constant.cs (LookupConstantValue): Implement.
+
+       (EmitConstant): Use the above in emitting the constant.
+
+       * expression.cs (MemberAccess::ResolveMemberAccess): Handle constants
+       that are user-defined by doing a LookupConstantValue on them.
+
+       (SimpleName::DoResolve): When we have a FieldExpr, cope with constants
+       too, like above.
+
+2001-11-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (BaseAccess, BaseIndexer): Also split this out.
+
+       (BaseAccess.DoResolve): Implement.
+
+       (MemberAccess.DoResolve): Split this routine into a
+       ResolveMemberAccess routine that can be used independently
+
+2001-11-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Probe, Is, As): Split Probe in two classes Is and
+       As that share bits of the implementation.  Is returns a boolean,
+       while As returns the Type that is being probed.
+
+2001-12-01  Ravi Pratap  <ravi@ximian.com>
+
+       * enum.cs (LookupEnumValue): Re-write various bits, return an object value
+       instead of a Literal - much easier.
+
+       (EnumInTransit): Remove - utterly useless :-)
+
+       (Populate): Re-write bits - remove duplicate code etc. The code is much neater now.
+
+       * expression.cs (MemberLookup): Cope with user-defined enums when they are in transit.
+
+       * enum.cs (LookupEnumValue): Auto-compute next values by going down the dependency
+       chain when we have no associated expression.
+
+2001-11-30  Ravi Pratap  <ravi@ximian.com>
+
+       * constant.cs (Define): Use Location while reporting the errror.
+
+       Also emit a warning when 'new' is used and there is no inherited
+       member to hide.
+
+       * enum.cs (EnumInTransit): Used to tell if an enum type is in the process of being 
+       populated.
+
+       (LookupEnumValue): Implement to lookup an enum member's value and define it
+       if necessary.
+
+       (Populate): Re-write accordingly to use the above routine.
+
+2001-11-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (This): Fix prototype for DoResolveLValue to
+       override the base class DoResolveLValue.
+
+       * cs-parser.cs: Report errors cs574 and cs575 (destructor
+       declarations) 
+
+       * ecore.cs (FieldExpr.EmitAssign): Handle value types specially
+       (we need to load the address of the field here).  This fixes
+       test-22. 
+
+       (FieldExpr.DoResolveLValue): Call the DoResolve
+       function to initialize the Instance expression.
+
+       * statement.cs (Foreach.Emit): Fix the bug where we did not invoke
+       correctly the GetEnumerator operation on a value type.
+
+       * cs-parser.jay: Add more simple parsing error catches.
+
+       * statement.cs (Switch): Add support for string switches.
+       Handle null specially.
+
+       * literal.cs (NullLiteral): Make NullLiteral objects singletons. 
+
+2001-11-28  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (local_constant_declaration): Use declare_local_constant.
+
+       (declare_local_constant): New helper function.
+
+       * statement.cs (AddConstant): Keep a separate record of constants
+
+       (IsConstant): Implement to determine if a variable is a constant.
+
+       (GetConstantExpression): Implement.
+
+       * expression.cs (LocalVariableReference): Handle the case when it is a constant.
+
+       * statement.cs (IsVariableDefined): Re-write.
+
+2001-11-27  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer::FindMembers): Look for constants
+       in the case when we are looking for MemberTypes.Field
+
+       * expression.cs (MemberAccess::DoResolve): Check that in the
+       case we are a FieldExpr and a Literal, we are not being accessed
+       by an instance reference.
+
+       * cs-parser.jay (local_constant_declaration): Implement.
+
+       (declaration_statement): Implement for constant declarations.
+
+2001-11-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Switch): Catch double defaults.
+
+       (Switch): More work on the switch() statement
+       implementation.  It works for integral values now, need to finish
+       string support.
+
+
+2001-11-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * ecore.cs (Expression.ConvertIntLiteral): New function to convert
+       integer literals into other integer literals.  To be used by
+       switch. 
+
+2001-11-24  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ArrayCreation): Get rid of ArrayExprs : we save
+       some memory.
+
+       (EmitDynamicInitializers): Cope with the above since we extract data
+       directly from ArrayData now.
+
+       (ExpectInitializers): Keep track of whether initializers are mandatory
+       or not.
+
+       (Bounds): Make it a hashtable to prevent the same dimension being 
+       recorded for every element in that dimension.
+
+       (EmitDynamicInitializers): Fix bug which prevented the Set array method
+       from being found.
+
+       Also fix bug which was causing the indices to be emitted in the reverse
+       order.
+
+2001-11-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ArrayCreation): Implement the bits that Ravi left
+       unfinished.  They do not work, because the underlying code is
+       sloppy.
+
+2001-11-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Remove bogus fixme.
+
+       * statement.cs (Switch, SwitchSection, SwithLabel): Started work
+       on Switch statement.
+
+2001-11-23  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (IsDelegateType, IsEnumType): Fix logic to determine
+       the same. 
+
+       * expression.cs (ArrayCreation::CheckIndices): Get rid of the require_constant
+       parameter. Apparently, any expression is allowed. 
+
+       (ValidateInitializers): Update accordingly.
+
+       (CheckIndices): Fix some tricky bugs thanks to recursion.
+
+       * delegate.cs (NewDelegate::DoResolve): Re-write large portions as 
+       I was being completely brain-dead.
+
+       (VerifyMethod, VerifyApplicability, VerifyDelegate): Make static
+       and re-write acordingly.
+
+       (DelegateInvocation): Re-write accordingly.
+
+       * expression.cs (ArrayCreation::Emit): Handle string initialization separately.
+
+       (MakeByteBlob): Handle types more correctly.
+
+       * expression.cs (ArrayCreation:Emit): Write preliminary code to do
+       initialization from expressions but it is incomplete because I am a complete
+       Dodo :-|
+
+2001-11-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (If.Emit): Fix a bug that generated incorrect code
+       on If.  Basically, we have to return `true' (ie, we do return to
+       our caller) only if both branches of the if return.
+
+       * expression.cs (Binary.Emit): LogicalOr and LogicalAnd are
+       short-circuit operators, handle them as short circuit operators. 
+
+       (Cast.DoResolve): Resolve type.
+       (Cast.Cast): Take an expression as the target type.
+
+       * cs-parser.jay (cast_expression): Remove old hack that only
+       allowed a limited set of types to be handled.  Now we take a
+       unary_expression and we resolve to a type during semantic
+       analysis.
+
+       Use the grammar productions from Rhys to handle casts (this is
+       not complete like Rhys syntax yet, we fail to handle that corner
+       case that C# has regarding (-x), but we will get there.
+
+2001-11-22  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (EmitFieldInitializer): Take care of the case when we have a
+       field which is an array type.
+
+       * cs-parser.jay (declare_local_variables): Support array initialization too.
+
+       * typemanager.cs (MakeKey): Implement.
+
+       (everywhere): Use the above appropriately.
+
+       * cs-parser.jay (for_statement): Update for array initialization while
+       declaring variables.
+
+       * ecore.cs : The error message was correct, it's the variable's names that
+       were misleading ;-) Make the code more readable.
+
+       (MemberAccess::DoResolve): Fix the code which handles Enum literals to set
+       the correct type etc.
+
+       (ConvertExplicit): Handle Enum types by examining the underlying type.
+
+2001-11-21  Ravi Pratap  <ravi@ximian.com>
+
+       * parameter.cs (GetCallingConvention): Always return
+       CallingConventions.Standard for now.
+
+2001-11-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Binary.ResolveOperator): Update the values of `l'
+       and `r' after calling DoNumericPromotions.
+
+       * ecore.cs: Fix error message (the types were in the wrong order).
+
+       * statement.cs (Foreach.ProbeCollectionType): Need to pass
+       BindingFlags.Instance as well 
+
+       * ecore.cs (Expression.TryImplicitIntConversion): Wrap the result
+       implicit int literal conversion in an empty cast so that we
+       propagate the right type upstream.
+
+       (UnboxCast): new class used to unbox value types.
+       (Expression.ConvertExplicit): Add explicit type conversions done
+       by unboxing.
+
+       (Expression.ImplicitNumericConversion): Oops, forgot to test for
+       the target type before applying the implicit LongLiterals to ULong
+       literal cast.
+
+2001-11-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay (for_statement): Reworked the way For works: now
+       we declare manually any variables that are introduced in
+       for_initializer to solve the problem of having out-of-band code
+       emition (that is what got for broken).
+
+       (declaration_statement): Perform the actual variable declaration
+       that used to be done in local_variable_declaration here.
+
+       (local_variable_declaration): Do not declare anything, just pass
+       the information on a DictionaryEntry
+
+2001-11-20  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ArrayCreation::CheckIndices): The story continues :-) Complete
+       re-write of the logic to now make it recursive.
+
+       (UpdateIndices): Re-write accordingly.
+
+       Store element data in a separate ArrayData list in the above methods.
+
+       (MakeByteBlob): Implement to dump the array data into a byte array.
+
+2001-11-19  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ArrayCreation): Factor out some code from ValidateInitializers
+       into CheckIndices.
+
+       * constant.cs (Define): Implement.
+
+       (EmitConstant): Re-write fully.
+
+       Pass in location info.
+
+       * class.cs (Populate, Emit): Call Constant::Define and Constant::EmitConstant
+       respectively.
+
+       * cs-parser.jay (constant_declarator): Use VariableDeclaration instead of
+       DictionaryEntry since we need location info too.
+
+       (constant_declaration): Update accordingly.
+
+       * expression.cs (ArrayCreation): Make ValidateInitializers simpler by factoring
+       code into another method : UpdateIndices.
+
+2001-11-18  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ArrayCreation::ValidateInitializers): Update to perform
+       some type checking etc.
+
+2001-11-17  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ArrayCreation::ValidateInitializers): Implement
+       bits to provide dimension info if the user skips doing that.
+
+       Update second constructor to store the rank correctly.
+
+2001-11-16  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ArrayCreation::ValidateInitializers): Poke around
+       and try to implement.
+
+       * ../errors/cs0150.cs : Add.
+
+       * ../errors/cs0178.cs : Add.
+
+2001-11-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs: Implement foreach on multi-dimensional arrays. 
+
+       * parameter.cs (Parameters.GetParameterByName): Also lookup the
+       name of the params argument.
+
+       * expression.cs: Use EmitStoreOpcode to get the right opcode while
+       initializing the array.
+
+       (ArrayAccess.EmitStoreOpcode): move the opcode generation here, so
+       we can use this elsewhere.
+
+       * statement.cs: Finish implementation of foreach for single
+       dimension arrays.
+
+       * cs-parser.jay: Use an out-of-band stack to pass information
+       around, I wonder why I need this.
+
+       foreach_block: Make the new foreach_block the current_block.
+
+       * parameter.cs (Parameters.GetEmptyReadOnlyParameters): New
+       function used to return a static Parameters structure.  Used for
+       empty parameters, as those are created very frequently.
+
+       * cs-parser.jay, class.cs: Use GetEmptyReadOnlyParameters
+
+2001-11-15  Ravi Pratap  <ravi@ximian.com>
+
+       * interface.cs : Default modifier is private, not public. The
+       make verify test passes again.
+
+2001-11-15  Ravi Pratap  <ravi@ximian.com>
+
+       * support.cs (ReflectionParameters): Fix logic to determine
+       whether the last parameter is a params one. Test 9 passes again.
+
+       * delegate.cs (Populate): Register the builders we define with
+       RegisterParameterForBuilder. Test 19 passes again.
+
+       * cs-parser.jay (property_declaration): Reference $6 instead
+       of $$ to get at the location.
+
+       (indexer_declaration): Similar stuff.
+
+       (attribute): Ditto.
+
+       * class.cs (Property): Register parameters for the Get and Set methods
+       if they exist. Test 23 passes again.
+
+       * expression.cs (ArrayCreation::Emit): Pass null for the method in the
+       call to EmitArguments as we are sure there aren't any params arguments. 
+       Test 32 passes again.
+
+       * suppor.cs (ParameterDesc, ParameterModifier): Fix trivial bug causing
+       IndexOutOfRangeException. 
+
+       * class.cs (Property::Define): Register property using TypeManager.RegisterProperty
+       Test 33 now passes again.
+
+2001-11-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Kill horrendous hack ($??? = lexer.Location) that
+       broke a bunch of things.  Will have to come up with a better way
+       of tracking locations.
+
+       * statement.cs: Implemented foreach for single dimension arrays.
+
+2001-11-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * enum.cs (Enum.Emit): Delay the lookup of loc until we run into
+       an error.  This removes the lookup from the critical path.
+
+       * cs-parser.jay: Removed use of temporary_loc, which is completely
+       broken. 
+
+2001-11-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * support.cs (ReflectionParameters.ParameterModifier): Report
+       whether the argument is a PARAMS argument or not.
+
+       * class.cs: Set the attribute `ParamArrayAttribute' on the
+       parameter argument.
+
+       * typemanager.cs: Define param_array_type (ParamArrayAttribute)
+       and cons_param_array_attribute (ConstructorInfo for
+       ParamArrayAttribute)., 
+
+       * codegen.cs: Emit the return using the `Return' statement, that
+       way we can report the error correctly for missing return values. 
+
+       * class.cs (Method.Emit): Clean up.
+
+       * expression.cs (Argument.Resolve): Take another argument: the
+       location where this argument is used.  Notice that this is not
+       part of the "Argument" class as to reduce the size of the
+       structure (we know the approximate location anyways).
+
+       Test if the argument is a variable-reference, if not, then
+       complain with a 206.
+
+       (Argument.Emit): Emit addresses of variables.
+
+       (Argument.FullDesc): Simplify.
+
+       (Invocation.DoResolve): Update for Argument.Resolve.
+
+       (ElementAccess.DoResolve): ditto.
+
+       * delegate.cs (DelegateInvocation.Emit): Invocation of Invoke
+       method should be virtual, as this method is always virtual.
+
+       (NewDelegate.DoResolve): Update for Argument.Resolve.
+
+       * class.cs (ConstructorInitializer.DoResolve): ditto.
+
+       * attribute.cs (Attribute.Resolve): ditto.
+
+2001-11-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Foreach.Emit): Use EmitAssign instead of Store.
+
+       * expression.cs (ParameterReference): Drop IStackStorage and implement
+       IAssignMethod instead. 
+
+       (LocalVariableReference): ditto.
+
+       * ecore.cs (FieldExpr): Drop IStackStorage and implement
+       IAssignMethod instead. 
+
+2001-11-13  Miguel de Icaza <miguel@ximian.com>
+
+       * parameter.cs, expression.cs, class.cs, ecore.cs: Made all
+       enumerations that are used in heavily used structures derive from
+       byte in a laughable and pathetic attempt to reduce memory usage.
+       This is the kind of pre-optimzations that you should not do at
+       home without adult supervision.
+
+       * expression.cs (UnaryMutator): New class, used to handle ++ and
+       -- separatedly from the other unary operators.  Cleans up the
+       code, and kills the ExpressionStatement dependency in Unary.
+
+       (Unary): Removed `method' and `Arguments' from this class, making
+       it smaller, and moving it all to SimpleCall, so I can reuse this
+       code in other locations and avoid creating a lot of transient data
+       strucutres when not required.
+
+       * cs-parser.jay: Adjust for new changes.
+
+2001-11-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * enum.cs (Enum.Populate): If there is a failure during
+       definition, return
+
+       * cs-parser.jay (opt_enum_base): we used to catch type errors
+       here, but this is really incorrect.  The type error should be
+       catched during semantic analysis.
+
+2001-12-11  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (operator_declarator, conversion_operator_declarator): Set
+       current_local_parameters as expected since I, in my stupidity, had forgotten
+       to do this :-)
+
+       * attribute.cs (GetValidPlaces): Fix stupid bug.
+
+       * class.cs (Method::Emit): Perform check on applicability of attributes.
+
+       (Constructor::Emit): Ditto.
+
+       (Field::Emit): Ditto.
+
+       (Field.Location): Store location information.
+
+       (Property, Event, Indexer, Operator): Ditto.
+
+       * cs-parser.jay (field_declaration): Pass in location for each field.
+
+       * ../errors/cs0592.cs : Add.
+
+2001-11-12  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (attribute_usage_type): New static member for System.AttributeUsage.
+
+       (InitCoreTypes): Update accordingly.
+
+       (RegisterAttrType, LookupAttr): Implement.
+
+       * attribute.cs (Attribute.Targets, AllowMultiple, Inherited): New fields to hold
+       info about the same.
+
+       (Resolve): Update to populate the above as necessary.
+
+       (Error592): Helper.
+
+       (GetValidPlaces): Helper to the above.
+
+       (CheckAttribute): Implement to perform validity of attributes on declarative elements.
+
+       * class.cs (TypeContainer::Emit): Update attribute emission code to perform checking etc.
+
+2001-11-12  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (Attribute::Resolve): Expand to handle named arguments too.
+
+       * ../errors/cs0617.cs : Add.
+
+2001-11-11  Ravi Pratap  <ravi@ximian.com>
+
+       * enum.cs (Emit): Rename to Populate to be more consistent with what
+       we expect it to do and when exactly it is called.
+
+       * class.cs, rootcontext.cs : Update accordingly.
+
+       * typemanager.cs (RegisterField, GetValue): Workarounds for the fact that
+       FieldInfo.GetValue does not work on dynamic types ! S.R.E lameness strikes again !
+
+       * enum.cs (Populate): Register fields with TypeManager.RegisterField.
+
+       * expression.cs (MemberAccess.DoResolve): Adjust code to obtain the value
+       of a fieldinfo using the above, when dealing with a FieldBuilder.
+
+2001-11-10  Ravi Pratap  <ravi@ximian.com>
+
+       * ../errors/cs0031.cs : Add.
+
+       * ../errors/cs1008.cs : Add.
+
+       * ../errrors/cs0543.cs : Add.
+
+       * enum.cs (DefineEnum): Check the underlying type and report an error if not a valid
+       enum type.
+
+       (FindMembers): Implement.
+
+       * typemanager.cs (FindMembers): Re-write to call the appropriate methods for
+       enums and delegates too.
+
+       (enum_types): Rename to builder_to_enum.
+
+       (delegate_types): Rename to builder_to_delegate.
+
+       * delegate.cs (FindMembers): Implement.
+
+2001-11-09  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (IsEnumType): Implement.
+
+       * enum.cs (Emit): Re-write parts to account for the underlying type
+       better and perform checking etc.
+
+       (GetNextDefaultValue): Helper to ensure we don't overshoot max value
+       of the underlying type.
+
+       * literal.cs (GetValue methods everywhere): Perform bounds checking and return
+       value
+
+       * enum.cs (error31): Helper to report error #31.
+
+       * cs-parser.jay (enum_declaration): Store location of each member too.
+
+       * enum.cs (member_to_location): New hashtable. 
+
+       (AddEnumMember): Update location hashtable.
+
+       (Emit): Use the location of each member while reporting errors.
+
+2001-11-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: A for_initializer if is a
+       local_variable_declaration really ammount to have an implicit
+       block with the variable declaration and no initializer for for.
+
+       * statement.cs (For.Emit): Cope with null initializers.
+
+       This fixes the infinite loop on for initializers.
+
+2001-11-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * enum.cs: More cleanup.
+
+       * ecore.cs: Remove dead code.
+
+       * class.cs (Property.Emit): More simplification.
+       (Event.Emit): ditto.
+
+       Reworked to have less levels of indentation.
+
+2001-11-08  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Property): Emit attributes.
+
+       (Field): Ditto.
+
+       (Event): Ditto.
+
+       (Indexer): Ditto.
+
+       (Operator): Ditto.
+
+       * enum.cs (Emit): Ditto.
+
+       * rootcontext.cs (ResolveTree, EmitCode, CloseTypes): Do the same for
+       Enums too.
+
+       * class.cs (Field, Event, etc.): Move attribute generation into the
+       Emit method everywhere.
+
+       * enum.cs (Enum): Revamp to use the same definition semantics as delegates so
+       we have a DefineEnum, CloseEnum etc. The previous way of doing things was not right
+       as we had no way of defining nested enums !
+
+       * rootcontext.cs : Adjust code accordingly.
+
+       * typemanager.cs (AddEnumType): To keep track of enum types separately.
+
+2001-11-07  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (EvalConstantExpression): Move into ecore.cs
+
+       * enum.cs (Enum): Rename some members and make them public and readonly
+       according to our convention.
+
+       * modifiers.cs (EnumAttr): Implement as we need to set only visibility flags,
+       nothing else.
+
+       * enum.cs (Enum::Define): Use the above instead of TypeAttr.
+
+       (Enum::Emit): Write a simple version for now which doesn't try to compute
+       expressions. I shall modify this to be more robust in just a while.
+
+       * class.cs (TypeContainer::Emit): Make sure we include Enums too.
+
+       (TypeContainer::CloseType): Create the Enum types too.
+
+       * attribute.cs (Resolve): Use the new Reduce method instead of EvalConstantExpression.
+
+       * expression.cs (EvalConstantExpression): Get rid of completely.
+
+       * enum.cs (Enum::Emit): Use the new expression reducer. Implement assigning
+       user-defined values and other cases.
+
+       (IsValidEnumLiteral): Helper function.
+
+       * expression.cs (ExprClassfromMemberInfo): Modify to not do any literalizing 
+       out there in the case we had a literal FieldExpr.
+
+       (MemberAccess:DoResolve): Do the literalizing of the FieldExpr here.
+
+       (Literalize): Revamp a bit to take two arguments.
+
+       (EnumLiteral): New class which derives from Literal to wrap enum literals.
+
+2001-11-06  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (compilation_unit): Remove extra opt_attributes for now.
+
+       * expression.cs (ArrayCreation::ValidateInitializers): Implement.
+
+       (Resolve): Use the above to ensure we have proper initializers.
+
+2001-11-05  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Expression::EvalConstantExpression): New method to 
+       evaluate constant expressions.
+
+       * attribute.cs (Attribute::Resolve): Modify bits to use the above function.
+
+2001-11-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ArrayCreation.Emit): Some bits to initialize data
+       in an array.
+
+       (Binary.ResolveOperator): Handle operator != (object a, object b)
+       and operator == (object a, object b);
+
+       (Binary.DoNumericPromotions): Indicate whether the numeric
+       promotion was possible.
+
+       (ArrayAccess.DoResolve, ArrayAccess.Emit, ArrayAccess.EmitAssign):
+       Implement.  
+
+       Made the ArrayAccess implement interface IAssignMethod instead of
+       IStackStore as the order in which arguments are passed reflects
+       this.
+
+       * assign.cs: Instead of using expr.ExprClass to select the way of
+       assinging, probe for the IStackStore/IAssignMethod interfaces.
+
+       * typemanager.cs: Load InitializeArray definition.
+
+       * rootcontext.cs (RootContext.MakeStaticData): Used to define
+       static data that can be used to initialize arrays. 
+
+2001-11-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Handle operator== and operator!= for booleans.
+
+       (Conditioal.Reduce): Implement reducer for the ?: operator.
+
+       (Conditional.Resolve): Implement dead code elimination.
+
+       (Binary.Resolve): Catch string literals and return a new
+       concatenated string.
+
+       (Unary.Reduce): Implement reduction of unary expressions.
+
+       * ecore.cs: Split out the expression core handling here.
+
+       (Expression.Reduce): New method used to perform constant folding
+       and CSE.  This is needed to support constant-expressions. 
+
+       * statement.cs (Statement.EmitBoolExpression): Pass true and false
+       targets, and optimize for !x.
+
+2001-11-04  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (Attribute::Resolve): Implement guts. Note that resolution
+       of an attribute gives us a CustomAttributeBuilder which we use accordingly to
+       set custom atttributes.
+
+       * literal.cs (Literal::GetValue): New abstract method to return the actual
+       value of the literal, cast as an object.
+
+       (*Literal): Implement GetValue method.
+
+       * cs-parser.jay (positional_argument_list, named_argument_list): Add not just plain
+       expressions to the arraylist but objects of type Argument.
+
+       * class.cs (TypeContainer::Emit): Emit our attributes too.
+
+       (Method::Emit, Constructor::Emit): Ditto.
+
+       * cs-parser.jay (constructor_declaration): Set attributes too, which we seemed
+       to be ignoring earlier.
+
+2001-11-03  Ravi Pratap  <ravi@ximian.com>
+
+       * attribute.cs (AttributeSection::Define): Implement to do the business
+       of constructing a CustomAttributeBuilder.
+
+       (Attribute): New trivial class. Increases readability of code.  
+
+       * cs-parser.jay : Update accordingly.
+
+       (positional_argument_list, named_argument_list, named_argument): New rules
+
+       (attribute_arguments): Use the above so that we are more correct.
+
+2001-11-02  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Invocation::IsParamsMethodApplicable): Implement
+       to perform all checks for a method with a params parameter.
+
+       (Invocation::OverloadResolve): Update to use the above method and therefore
+       cope correctly with params method invocations.
+
+       * support.cs (InternalParameters::ParameterDesc): Provide a desc for 
+       params too.
+
+       * class.cs (ConstructorInitializer::Resolve): Make sure we look for Non-public
+       constructors in our parent too because we can't afford to miss out on 
+       protected ones ;-)
+
+       * attribute.cs (AttributeSection): New name for the class Attribute
+
+       Other trivial changes to improve readability.
+
+       * cs-parser.jay (opt_attributes, attribute_section etc.): Modify to
+       use the new class names.
+
+2001-11-01  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Method::Define): Complete definition for params types too
+
+       (Indexer::Define): Ditto.
+
+       * support.cs (InternalParameters::ParameterType, ParameterDesc, ParameterModifier):
+       Cope everywhere with a request for info about the array parameter.
+
+2001-11-01  Ravi Pratap  <ravi@ximian.com>
+
+       * tree.cs (RecordNamespace): Fix up to check for the correct key.
+
+       * cs-parser.jay (GetQualifiedIdentifier): New Helper method used in 
+       local_variable_type to extract the string corresponding to the type.
+
+       (local_variable_type): Fixup the action to use the new helper method.
+
+       * codegen.cs : Get rid of RefOrOutParameter, it's not the right way to 
+       go.
+
+       * expression.cs : Clean out code which uses the above.
+
+2001-10-31  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (RegisterMethod): Check if we already have an existing key
+       and bale out if necessary by returning a false.
+
+       (RegisterProperty): Ditto.
+
+       * class.cs (everywhere): Check the return value from TypeManager.RegisterMethod
+       and print out appropriate error messages.
+
+       * interface.cs (everywhere): Ditto.
+
+       * cs-parser.jay (property_declaration, event_declaration, indexer_declaration): Pass
+       location to constructor.
+
+       * class.cs (Property, Event, Indexer): Update accordingly.
+
+       * ../errors/cs111.cs : Added.
+
+       * expression.cs (Invocation::IsApplicable): New static method to determine applicability
+       of a method, as laid down by the spec.
+
+       (Invocation::OverloadResolve): Use the above method.
+
+2001-10-31  Ravi Pratap  <ravi@ximian.com>
+
+       * support.cs (InternalParameters): Get rid of crap taking in duplicate info. We
+       now take a TypeContainer and a Parameters object.
+
+       (ParameterData): Modify return type of ParameterModifier method to be 
+       Parameter.Modifier and not a string.
+
+       (ReflectionParameters, InternalParameters): Update accordingly.
+
+       * expression.cs (Argument::GetParameterModifier): Same here.
+
+       * support.cs (InternalParameters::ParameterType): Find a better way of determining
+       if we are a ref/out parameter. Actually, the type shouldn't be holding the '&'
+       symbol in it at all so maybe this is only for now.
+
+2001-10-30  Ravi Pratap  <ravi@ximian.com>
+
+       * support.cs (InternalParameters): Constructor now takes an extra argument 
+       which is the actual Parameters class.
+
+       (ParameterDesc): Update to provide info on ref/out modifiers.
+
+       * class.cs (everywhere): Update call to InternalParameters to pass in
+       the second argument too.
+
+       * support.cs (ParameterData): Add ParameterModifier, which is a method 
+       to return the modifier info [ref/out etc]
+
+       (InternalParameters, ReflectionParameters): Implement the above.
+
+       * expression.cs (Argument::ParameterModifier): Similar function to return
+       info about the argument's modifiers.
+
+       (Invocation::OverloadResolve): Update to take into account matching modifiers 
+       too.
+
+       * class.cs (Indexer::Define): Actually define a Parameter object and put it onto
+       a new SetFormalParameters object which we pass to InternalParameters.
+
+2001-10-30  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (NewArray): Merge into the ArrayCreation class.
+
+2001-10-29  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (NewArray): Merge classes NewBuiltinArray and 
+       NewUserdefinedArray into one as there wasn't much of a use in having
+       two separate ones.
+
+       * expression.cs (Argument): Change field's name to ArgType from Type.
+
+       (Type): New readonly property which returns the proper type, taking into 
+       account ref/out modifiers.
+
+       (everywhere): Adjust code accordingly for the above.
+
+       * codegen.cs (EmitContext.RefOrOutParameter): New field to determine
+       whether we are emitting for a ref or out parameter.
+
+       * expression.cs (Argument::Emit): Use the above field to set the state.
+
+       (LocalVariableReference::Emit): Update to honour the flag and emit the
+       right stuff.
+
+       * parameter.cs (Attributes): Set the correct flags for ref parameters.
+
+       * expression.cs (Argument::FullDesc): New function to provide a full desc.
+
+       * support.cs (ParameterData): Add method ParameterDesc to the interface.
+
+       (ReflectionParameters, InternalParameters): Implement the above method.
+
+       * expression.cs (Invocation::OverloadResolve): Use the new desc methods in
+       reporting errors.
+
+       (Invocation::FullMethodDesc): Ditto. 
+
+2001-10-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Add extra production for the second form of array
+       creation. 
+
+       * expression.cs (ArrayCreation): Update to reflect the above
+       change. 
+
+       * Small changes to prepare for Array initialization.
+
+2001-10-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (ImplementsInterface): interface might be null;
+       Deal with this problem;
+
+       Also, we do store negative hits on the cache (null values), so use
+       this instead of calling t.GetInterfaces on the type everytime.
+
+2001-10-28  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (IsBuiltinType): New method to help determine the same.
+
+       * expression.cs (New::DoResolve): Get rid of array creation code and instead
+       split functionality out into different classes.
+
+       (New::FormArrayType): Move into NewBuiltinArray.
+
+       (Invocation::EmitArguments): Get rid of the MethodBase argument. Appears
+       quite useless.
+
+       (NewBuiltinArray): New class to handle creation of built-in arrays.
+
+       (NewBuiltinArray::DoResolve): Implement guts of array creation. Also take into
+       account creation of one-dimensional arrays.
+
+       (::Emit): Implement to use Newarr and Newobj opcodes accordingly.
+
+       (NewUserdefinedArray::DoResolve): Implement.
+
+       * cs-parser.jay (local_variable_type): Fix up to add the rank to the variable too.
+
+       * typemanager.cs (AddModule): Used to add a ModuleBuilder to the list of modules
+       we maintain inside the TypeManager. This is necessary to perform lookups on the
+       module builder.
+
+       (LookupType): Update to perform GetType on the module builders too.     
+
+       * driver.cs (Driver): Add the ModuleBuilder to the list maintained by the TypeManager.
+
+       * exprssion.cs (NewUserdefinedArray::Emit): Implement.
+
+2001-10-23  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (New::DoResolve): Implement guts of array creation.
+
+       (New::FormLookupType): Rename to FormArrayType and modify ever so slightly.
+
+2001-10-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Fix bug I introduced lsat night that broke
+       Delegates. 
+
+       (Expression.Resolve): Report a 246 error (can not resolve name)
+       if we find a SimpleName in the stream.
+
+       (Expression.ResolveLValue): Ditto.
+
+       (Expression.ResolveWithSimpleName): This function is a variant of
+       ResolveName, this one allows SimpleNames to be returned without a
+       warning.  The only consumer of SimpleNames is MemberAccess
+
+2001-10-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Invocation::DoResolve): Catch SimpleNames that
+       might arrive here.  I have my doubts that this is correct.
+
+       * statement.cs (Lock): Implement lock statement.
+
+       * cs-parser.jay: Small fixes to support `lock' and `using'
+
+       * cs-tokenizer.cs: Remove extra space
+
+       * driver.cs: New flag --checked, allows to turn on integer math
+       checking. 
+
+       * typemanger.cs: Load methodinfos for Threading.Monitor.Enter and
+       Threading.Monitor.Exit 
+
+2001-10-23  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (IndexerAccess::DoResolveLValue): Set the
+       Expression Class to be IndexerAccess.
+
+       Notice that Indexer::DoResolve sets the eclass to Value.
+
+2001-10-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer::Emit): Emit code for indexers.
+
+       * assign.cs (IAssignMethod): New interface implemented by Indexers
+       and Properties for handling assignment.
+
+       (Assign::Emit): Simplify and reuse code. 
+
+       * expression.cs (IndexerAccess, PropertyExpr): Implement
+       IAssignMethod, clean up old code. 
+
+2001-10-22  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (ImplementsInterface): New method to determine if a type
+       implements a given interface. Provides a nice cache too.
+
+       * expression.cs (ImplicitReferenceConversion): Update checks to use the above
+       method.
+
+       (ConvertReferenceExplicit): Ditto.
+
+       * delegate.cs (Delegate::Populate): Update to define the parameters on the 
+       various methods, with correct names etc.
+
+       * class.cs (Operator::OpType): New members Operator.UnaryPlus and 
+       Operator.UnaryNegation.
+
+       * cs-parser.jay (operator_declarator): Be a little clever in the case where
+       we have a unary plus or minus operator.
+
+       * expression.cs (Unary): Rename memebers of Operator enum to UnaryPlus and 
+       UnaryMinus.
+
+       * everywhere : update accordingly.
+
+       * everywhere : Change Negate and BitComplement to LogicalNot and OnesComplement
+       respectively.
+
+       * class.cs (Method::Define): For the case where we are implementing a method
+       inherited from an interface, we need to set the MethodAttributes.Final flag too. 
+       Also set MethodAttributes.NewSlot and MethodAttributes.HideBySig.
+
+2001-10-21  Ravi Pratap  <ravi@ximian.com>
+
+       * interface.cs (FindMembers): Implement to work around S.R.E
+       lameness.
+
+       * typemanager.cs (IsInterfaceType): Implement.
+
+       (FindMembers): Update to handle interface types too.
+
+       * expression.cs (ImplicitReferenceConversion): Re-write bits which
+       use IsAssignableFrom as that is not correct - it doesn't work.
+
+       * delegate.cs (DelegateInvocation): Derive from ExpressionStatement
+       and accordingly override EmitStatement.
+
+       * expression.cs (ConvertReferenceExplicit): Re-write similary, this time
+       using the correct logic :-)
+
+2001-10-19  Ravi Pratap  <ravi@ximian.com>
+
+       * ../errors/cs-11.cs : Add to demonstrate error -11 
+
+2001-10-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs (Assign::Resolve): Resolve right hand side first, and
+       then pass this as a hint to ResolveLValue.
+
+       * expression.cs (FieldExpr): Add Location information
+
+       (FieldExpr::LValueResolve): Report assignment to readonly
+       variable. 
+
+       (Expression::ExprClassFromMemberInfo): Pass location information.
+
+       (Expression::ResolveLValue): Add new method that resolves an
+       LValue. 
+
+       (Expression::DoResolveLValue): Default invocation calls
+       DoResolve. 
+
+       (Indexers): New class used to keep track of indexers in a given
+       Type. 
+
+       (IStackStore): Renamed from LValue, as it did not really describe
+       what this did.  Also ResolveLValue is gone from this interface and
+       now is part of Expression.
+
+       (ElementAccess): Depending on the element access type
+
+       * typemanager.cs: Add `indexer_name_type' as a Core type
+       (System.Runtime.CompilerServices.IndexerNameAttribute)
+
+       * statement.cs (Goto): Take a location.
+
+2001-10-18  Ravi Pratap  <ravi@ximian.com>
+
+       * delegate.cs (Delegate::VerifyDelegate): New method to verify
+       if two delegates are compatible.
+
+       (NewDelegate::DoResolve): Update to take care of the case when
+       we instantiate a delegate from another delegate.
+
+       * typemanager.cs (FindMembers): Don't even try to look up members
+       of Delegate types for now.
+
+2001-10-18  Ravi Pratap  <ravi@ximian.com>
+
+       * delegate.cs (NewDelegate): New class to take care of delegate
+       instantiation.
+
+       * expression.cs (New): Split the delegate related code out into 
+       the NewDelegate class.
+
+       * delegate.cs (DelegateInvocation): New class to handle delegate 
+       invocation.
+
+       * expression.cs (Invocation): Split out delegate related code into
+       the DelegateInvocation class.
+
+2001-10-17  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (New::DoResolve): Implement delegate creation fully
+       and according to the spec.
+
+       (New::DoEmit): Update to handle delegates differently.
+
+       (Invocation::FullMethodDesc): Fix major stupid bug thanks to me
+       because of which we were printing out arguments in reverse order !
+
+       * delegate.cs (VerifyMethod): Implement to check if the given method
+       matches the delegate.
+
+       (FullDelegateDesc): Implement.
+
+       (VerifyApplicability): Implement.
+
+       * expression.cs (Invocation::DoResolve): Update to accordingly handle
+       delegate invocations too.
+
+       (Invocation::Emit): Ditto.
+
+       * ../errors/cs1593.cs : Added.
+
+       * ../errors/cs1594.cs : Added.
+
+       * delegate.cs (InstanceExpression, TargetMethod): New properties.
+
+2001-10-16  Ravi Pratap  <ravi@ximian.com>
+
+       * typemanager.cs (intptr_type): Core type for System.IntPtr
+
+       (InitCoreTypes): Update for the same.
+
+       (iasyncresult_type, asynccallback_type): Ditto.
+
+       * delegate.cs (Populate): Fix to use System.Intptr as it is indeed
+       correct.
+
+       * typemanager.cs (AddDelegateType): Store a pointer to the Delegate class
+       too.
+
+       * delegate.cs (ConstructorBuilder, InvokeBuilder, ...): New members to hold
+       the builders for the 4 members of a delegate type :-)
+
+       (Populate): Define the BeginInvoke and EndInvoke methods on the delegate
+       type.
+
+       * expression.cs (New::DoResolve): Implement guts for delegate creation.
+
+       * ../errors/errors.txt : Update for an error (-11) which only we catch :-)
+
+2001-10-15  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Break::Emit): Implement.   
+       (Continue::Emit): Implement.
+
+       (For::Emit): Track old being/end loops;  Set Begin loop, ack end loop
+       (While::Emit): Track old being/end loops;  Set Begin loop, ack end loop
+       (Do::Emit): Track old being/end loops;  Set Begin loop, ack end loop
+       (Foreach::Emit): Track old being/end loops;  Set Begin loop, ack
+       end loop
+
+       * codegen.cs (EmitContext::LoopEnd, EmitContext::LoopBegin): New
+       properties that track the label for the current loop (begin of the
+       loop and end of the loop).
+
+2001-10-15  Ravi Pratap  <ravi@ximian.com>
+
+       * delegate.cs (Emit): Get rid of it as there doesn't seem to be any ostensible
+       use of emitting anything at all.
+
+       * class.cs, rootcontext.cs : Get rid of calls to the same.
+
+       * delegate.cs (DefineDelegate): Make sure the class we define is also sealed.
+
+       (Populate): Define the constructor correctly and set the implementation
+       attributes.
+
+       * typemanager.cs (delegate_types): New hashtable to hold delegates that
+       have been defined.
+
+       (AddDelegateType): Implement.
+
+       (IsDelegateType): Implement helper method.
+
+       * delegate.cs (DefineDelegate): Use AddDelegateType instead of AddUserType.
+
+       * expression.cs (New::DoResolve): Check if we are trying to instantiate a delegate type
+       and accordingly handle it.
+
+       * delegate.cs (Populate): Take TypeContainer argument.
+       Implement bits to define the Invoke method. However, I still haven't figured out
+       how to take care of the native int bit :-(
+
+       * cs-parser.jay (delegate_declaration): Fixed the bug that I had introduced :-) 
+       Qualify the name of the delegate, not its return type !
+
+       * expression.cs (ImplicitReferenceConversion): Implement guts of implicit array
+       conversion.
+
+       (StandardConversionExists): Checking for array types turns out to be recursive.
+
+       (ConvertReferenceExplicit): Implement array conversion.
+
+       (ExplicitReferenceConversionExists): New method to determine precisely that :-)
+
+2001-10-12  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (delegate_declaration): Store the fully qualified
+       name as it is a type declaration.
+
+       * delegate.cs (ReturnType, Name): Rename members to these. Make them 
+       readonly.
+
+       (DefineDelegate): Renamed from Define. Does the same thing essentially,
+       as TypeContainer::DefineType.
+
+       (Populate): Method in which all the definition of the various methods (Invoke)
+       etc is done.
+
+       (Emit): Emit any code, if necessary. I am not sure about this really, but let's
+       see.
+
+       (CloseDelegate): Finally creates the delegate.
+
+       * class.cs (TypeContainer::DefineType): Update to define delegates.
+       (Populate, Emit and CloseType): Do the same thing here too.
+
+       * rootcontext.cs (ResolveTree, PopulateTypes, EmitCode, CloseTypes): Include
+       delegates in all these operations.
+
+2001-10-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: LocalTemporary: a new expression used to
+       reference a temporary that has been created.
+
+       * assign.cs: Handle PropertyAccess back here, so that we can
+       provide the proper semantic access to properties.
+
+       * expression.cs (Expression::ConvertReferenceExplicit): Implement
+       a few more explicit conversions. 
+
+       * modifiers.cs: `NEW' modifier maps to HideBySig.
+
+       * expression.cs (PropertyExpr): Make this into an
+       ExpressionStatement, and support the EmitStatement code path. 
+
+       Perform get/set error checking, clean up the interface.
+
+       * assign.cs: recognize PropertyExprs as targets, and if so, turn
+       them into toplevel access objects.
+
+2001-10-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: PropertyExpr::PropertyExpr: use work around the
+       SRE.
+
+       * typemanager.cs: Keep track here of our PropertyBuilders again to
+       work around lameness in SRE.
+
+2001-10-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (LValue::LValueResolve): New method in the
+       interface, used to perform a second resolution pass for LValues. 
+
+       (This::DoResolve): Catch the use of this in static methods.
+
+       (This::LValueResolve): Implement.
+
+       (This::Store): Remove warning, assigning to `this' in structures
+       is 
+
+       (Invocation::Emit): Deal with invocation of
+       methods on value types.  We need to pass the address to structure
+       methods rather than the object itself.  (The equivalent code to
+       emit "this" for structures leaves the entire structure on the
+       stack instead of a pointer to it). 
+
+       (ParameterReference::DoResolve): Compute the real index for the
+       argument based on whether the method takes or not a `this' pointer
+       (ie, the method is static).
+
+       * codegen.cs (EmitContext::GetTemporaryStorage): Used to store
+       value types returned from functions when we need to invoke a
+       method on the sturcture.
+
+
+2001-10-11  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer::DefineType): Method to actually do the business of
+       defining the type in the Modulebuilder or Typebuilder. This is to take
+       care of nested types which need to be defined on the TypeBuilder using
+       DefineNestedMethod.
+
+       (TypeContainer::GetClassBases): Implement. Essentially the code from the 
+       methods in RootContext, only ported to be part of TypeContainer.
+
+       (TypeContainer::GetInterfaceOrClass): Ditto.
+
+       (TypeContainer::LookupInterfaceOrClass, ::MakeFQN): Ditto.
+
+       * interface.cs (Interface::DefineInterface): New method. Does exactly
+       what RootContext.CreateInterface did earlier, only it takes care of nested types 
+       too.
+
+       (Interface::GetInterfaces): Move from RootContext here and port.
+
+       (Interface::GetInterfaceByName): Same here.
+
+       * rootcontext.cs (ResolveTree): Re-write.
+
+       (PopulateTypes): Re-write.
+
+       * class.cs (TypeContainer::Populate): Populate nested types too.
+       (TypeContainer::Emit): Emit nested members too.
+
+       * typemanager.cs (AddUserType): Do not make use of the FullName property,
+       instead just use the name argument passed in as it is already fully
+       qualified.
+
+       (FindMembers): Check in the Builders to TypeContainer mapping instead of the name
+       to TypeContainer mapping to see if a type is user-defined.
+
+       * class.cs (TypeContainer::CloseType): Implement. 
+
+       (TypeContainer::DefineDefaultConstructor): Use Basename, not Name while creating
+       the default constructor.
+
+       (TypeContainer::Populate): Fix minor bug which led to creating default constructors
+       twice.
+
+       (Constructor::IsDefault): Fix up logic to determine if it is the default constructor
+
+       * interface.cs (CloseType): Create the type here.
+
+       * rootcontext.cs (CloseTypes): Re-write to recursively close types by running through
+       the hierarchy.
+
+       Remove all the methods which are now in TypeContainer.
+
+2001-10-10  Ravi Pratap  <ravi@ximian.com>
+
+       * delegate.cs (Define): Re-write bits to define the delegate
+       correctly.
+
+2001-10-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * makefile: Renamed the compiler to `mcs.exe' instead of compiler.exe
+
+       * expression.cs (ImplicitReferenceConversion): handle null as well
+       as a source to convert to any reference type.
+
+       * statement.cs (Return): Perform any implicit conversions to
+       expected return type.  
+
+       Validate use of return statement.  
+
+       * codegen.cs (EmitContext): Pass the expected return type here.
+
+       * class.cs (Method, Constructor, Property): Pass expected return
+       type to EmitContext.
+
+2001-10-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Make DoResolve take an EmitContext instead of a
+       TypeContainer.
+
+       Replaced `l' and `location' for `loc', for consistency.
+
+       (Error, Warning): Remove unneeded Tc argument.
+
+       * assign.cs, literal.cs, constant.cs: Update to new calling
+       convention. 
+
+       * codegen.cs: EmitContext now contains a flag indicating whether
+       code is being generated in a static method or not.
+
+       * cs-parser.jay: DecomposeQI, new function that replaces the old
+       QualifiedIdentifier.  Now we always decompose the assembled
+       strings from qualified_identifier productions into a group of
+       memberaccesses.
+
+2001-10-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs: Deal with field-less struct types correctly now
+       by passing the size option to Define Type.
+
+       * class.cs: Removed hack that created one static field. 
+
+2001-10-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs: Moved most of the code generation here. 
+
+2001-10-09  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (New::DoResolve): Revert changes for array creation, doesn't
+       seem very right.
+
+       (ElementAccess): Remove useless bits for now - keep checks as the spec
+       says.
+
+2001-10-08  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ElementAccess::DoResolve): Remove my crap code
+       and start performing checks according to the spec.
+
+2001-10-07  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (type_suffix*): Remove - they are redundant. Use
+       rank_specifiers instead.
+
+       (rank_specifiers): Change the order in which the rank specifiers are stored
+
+       (local_variable_declaration): Use opt_rank_specifier instead of type_suffixes.
+
+       * expression.cs (ElementAccess): Implement the LValue interface too.
+
+2001-10-06  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ConvertExplicitStandard): Add. Same as ConvertExplicit
+       except that user defined conversions are not included.
+
+       (UserDefinedConversion): Update to use the ConvertExplicitStandard to 
+       perform the conversion of the return type, if necessary.
+
+       (New::DoResolve): Check whether we are creating an array or an object
+       and accordingly do the needful.
+
+       (New::Emit): Same here.
+
+       (New::DoResolve): Implement guts of array creation.
+
+       (New::FormLookupType): Helper function.
+
+2001-10-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs: Removed most of the code generation here, and move the
+       corresponding code generation bits to the statement classes. 
+
+       Added support for try/catch/finalize and throw.
+
+       * cs-parser.jay: Added support for try/catch/finalize.
+
+       * class.cs: Catch static methods having the flags override,
+       virtual or abstract.
+
+       * expression.cs (UserCast): This user cast was not really doing
+       what it was supposed to do.  Which is to be born in fully resolved
+       state.  Parts of the resolution were being performed at Emit time! 
+
+       Fixed this code.
+
+2001-10-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs: Implicity convert the result from UserCast.
+
+2001-10-05  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Expression::FindMostEncompassingType): Fix bug which
+       prevented it from working correctly. 
+
+       (ConvertExplicit): Make the first try, a call to ConvertImplicitStandard, not
+       merely ConvertImplicit.
+
+2001-10-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs: Make the LookupTypeContainer function static,
+       and not per-instance.  
+
+       * class.cs: Make static FindMembers (the one that takes a Type
+       argument). 
+
+       * codegen.cs: Add EmitForeach here.
+
+       * cs-parser.jay: Make foreach a toplevel object instead of the
+       inline expansion, as we need to perform semantic analysis on it. 
+
+2001-10-05  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Expression::ImplicitUserConversion): Rename to
+       UserDefinedConversion.
+
+       (Expression::UserDefinedConversion): Take an extra argument specifying 
+       whether we look for explicit user conversions too.
+
+       (Expression::ImplicitUserConversion): Make it a call to UserDefinedConversion.
+
+       (UserDefinedConversion): Incorporate support for user defined explicit conversions.
+
+       (ExplicitUserConversion): Make it a call to UserDefinedConversion
+       with the appropriate arguments.
+
+       * cs-parser.jay (cast_expression): Record location too.
+
+       * expression.cs (Cast): Record location info.
+
+       (Expression::ConvertExplicit): Take location argument.
+
+       (UserImplicitCast): Change name to UserCast. Take an extra constructor argument
+       to determine if we are doing explicit conversions.
+
+       (UserCast::Emit): Update accordingly.
+
+       (Expression::ConvertExplicit): Report an error if everything fails.
+
+       * ../errors/cs0030.cs : Add.
+
+2001-10-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * modifiers.cs: If the ABSTRACT keyword is present, also set the
+       virtual and newslot bits. 
+
+       * class.cs (TypeContainer::RegisterRequiredImplementations):
+       Record methods we need.
+
+       (TypeContainer::MakeKey): Helper function to make keys for
+       MethodBases, since the Methodbase key is useless.
+
+       (TypeContainer::Populate): Call RegisterRequiredImplementations
+       before defining the methods.   
+
+       Create a mapping for method_builders_to_methods ahead of time
+       instead of inside a tight loop.
+
+       (::RequireMethods):  Accept an object as the data to set into the
+       hashtable so we can report interface vs abstract method mismatch.
+
+2001-10-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * report.cs: Make all of it static.
+
+       * rootcontext.cs: Drop object_type and value_type computations, as
+       we have those in the TypeManager anyways.
+
+       Drop report instance variable too, now it is a global.
+
+       * driver.cs: Use try/catch on command line handling.
+
+       Add --probe option to debug the error reporting system with a test
+       suite. 
+
+       * report.cs: Add support for exiting program when a probe
+       condition is reached.
+
+2001-10-03  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Binary::DoNumericPromotions): Fix the case when
+       we do a forcible conversion regardless of type, to check if 
+       ForceConversion returns a null.
+
+       (Binary::error19): Use location to report error.
+
+       (Unary::error23): Use location here too.
+
+       * ../errors/cs0019.cs : Check in.
+
+       * ../errors/cs0023.cs : Check in.
+
+       * expression.cs (Expression.MemberLookup): Return null for a rather esoteric
+       case of a non-null MethodInfo object with a length of 0 !
+
+       (Binary::ResolveOperator): Flag error if overload resolution fails to find
+       an applicable member - according to the spec :-)
+       Also fix logic to find members in base types.
+
+       (Unary::ResolveOperator): Same here.
+
+       (Unary::report23): Change name to error23 and make first argument a TypeContainer
+       as I was getting thoroughly confused between this and error19 :-)
+
+       * expression.cs (Expression::ImplicitUserConversion): Re-write fully
+       (::FindMostEncompassedType): Implement.
+       (::FindMostEncompassingType): Implement.
+       (::StandardConversionExists): Implement.
+
+       (UserImplicitCast): Re-vamp. We now need info about most specific
+       source and target types so that we can do the necessary conversions.
+
+       (Invocation::MakeUnionSet): Completely re-write to make sure we form a proper
+       mathematical union with no duplicates.
+
+2001-10-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs (RootContext::PopulateTypes): Populate containers
+       in order from base classes to child classes, so that we can in
+       child classes look up in our parent for method names and
+       attributes (required for handling abstract, virtual, new, override
+       constructs: we need to instrospect our base class, and if we dont
+       populate the classes in order, the introspection might be
+       incorrect.  For example, a method could query its parent before
+       the parent has any methods and would determine that the parent has
+       no abstract methods (while it could have had them)).
+
+       (RootContext::CreateType): Record the order in which we define the
+       classes.
+
+2001-10-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer::Populate): Also method definitions can
+       fail now, keep track of this.
+
+       (TypeContainer::FindMembers): Implement support for
+       DeclaredOnly/noDeclaredOnly flag.
+
+       (Constructor::Emit) Return the ConstructorBuilder.
+
+       (Method::Emit) Return the MethodBuilder. 
+       Check for abstract or virtual methods to be public.
+
+       * rootcontext.cs (RootContext::CreateType): Register all the
+       abstract methods required for the class to be complete and the
+       interface methods that must be implemented. 
+
+       * cs-parser.jay: Report error 501 (method requires body if it is
+       not marked abstract or extern).
+
+       * expression.cs (TypeOf::Emit): Implement.
+
+       * typemanager.cs: runtime_handle_type, new global type.
+
+       * class.cs (Property::Emit): Generate code for properties.
+
+2001-10-02  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Unary::ResolveOperator): Find operators on base type
+       too - we now conform exactly to the spec.
+
+       (Binary::ResolveOperator): Same here.
+
+       * class.cs (Operator::Define): Fix minor quirk in the tests.
+
+       * ../errors/cs0215.cs : Added.
+
+       * ../errors/cs0556.cs : Added.
+
+       * ../errors/cs0555.cs : Added.
+
+2001-10-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-tokenizer.cs: Reimplemented Location to be a struct with a
+       single integer which is really efficient
+
+2001-10-01  Ravi Pratap  <ravi@ximian.com>
+
+       *  expression.cs (Expression::ImplicitUserConversion): Use location
+       even in the case when we are examining True operators.
+       * class.cs (Operator::Define): Perform extensive checks to conform
+       with the rules for operator overloading in the spec.
+
+       * expression.cs (Expression::ImplicitReferenceConversion): Implement
+       some of the other conversions mentioned in the spec.
+
+       * typemanager.cs (array_type): New static member for the System.Array built-in
+       type.
+
+       (cloneable_interface): For System.ICloneable interface.
+
+       * driver.cs (Driver::Driver): Initialize TypeManager's core types even before
+       we start resolving the tree and populating types.
+
+       * ../errors/errors.txt : Update for error numbers -7, -8, -9, -10
+2001-10-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Expression::ExprClassFromMemberInfo,
+       Expression::Literalize): Create literal expressions from
+       FieldInfos which are literals.
+
+       (ConvertNumericExplicit, ImplicitNumericConversion): Fix a few
+       type casts, because they were wrong.  The test suite in tests
+       caught these ones.
+
+       (ImplicitNumericConversion): ushort to ulong requires a widening
+       cast. 
+
+       Int32 constant to long requires widening cast as well.
+
+       * literal.cs (LongLiteral::EmitLong): Do not generate i4 constants
+       for integers because the type on the stack is not i4.
+
+2001-09-30  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (report118): require location argument. 
+
+       * parameter.cs: Do not dereference potential null value.
+
+       * class.cs: Catch methods that lack the `new' keyword when
+       overriding a name.  Report warnings when `new' is used without
+       anything being there to override.
+
+       * modifiers.cs: Handle `NEW' as MethodAttributes.NewSlot.
+
+       * class.cs: Only add constructor to hashtable if it is non-null
+       (as now constructors can fail on define).
+
+       (TypeManager, Class, Struct): Take location arguments.
+
+       Catch field instance initialization in structs as errors.
+
+       accepting_filter: a new filter for FindMembers that is static so
+       that we dont create an instance per invocation.
+
+       (Constructor::Define): Catch errors where a struct constructor is
+       parameterless 
+
+       * cs-parser.jay: Pass location information for various new
+       constructs. 
+
+       * delegate.cs (Delegate): take a location argument.
+
+       * driver.cs: Do not call EmitCode if there were problesm in the
+       Definition of the types, as many Builders wont be there. 
+
+       * decl.cs (Decl::Decl): Require a location argument.
+
+       * cs-tokenizer.cs: Handle properly hex constants that can not fit
+       into integers, and find the most appropiate integer for it.
+
+       * literal.cs: Implement ULongLiteral.
+
+       * rootcontext.cs: Provide better information about the location of
+       failure when CreateType fails.
+
+2001-09-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs (RootContext::PopulateTypes): Populates structs
+       as well.
+
+       * expression.cs (Binary::CheckShiftArguments): Add missing type
+       computation.
+       (Binary::ResolveOperator): Add type to the logical and and logical
+       or, Bitwise And/Or and Exclusive Or code paths, it was missing
+       before.
+
+       (Binary::DoNumericPromotions): In the case where either argument
+       is ulong (and most signed types combined with ulong cause an
+       error) perform implicit integer constant conversions as well.
+
+2001-09-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (UserImplicitCast): Method should always be
+       non-null. 
+       (Invocation::BetterConversion): Simplified test for IntLiteral.
+
+       (Expression::ImplicitNumericConversion): Split this routine out.
+       Put the code that performs implicit constant integer conversions
+       here. 
+
+       (Expression::Resolve): Become a wrapper around DoResolve so we can
+       check eclass and type being set after resolve.
+
+       (Invocation::Badness): Remove this dead function
+
+       (Binary::ResolveOperator): Do not compute the expensive argumnets
+       unless we have a union for it.
+
+       (Probe::Emit): Is needs to do an isinst and then
+       compare against null.
+
+       (::CanConvert): Added Location argument.  If the Location argument
+       is null (Location.Null), then we do not report errors.  This is
+       used by the `probe' mechanism of the Explicit conversion.  We do
+       not want to generate an error for something that the user
+       explicitly requested to be casted.  But the pipeline for an
+       explicit cast first tests for potential implicit casts.
+
+       So for now, if the Location is null, it means `Probe only' to
+       avoid adding another argument.   Might have to revise this
+       strategy later.
+
+       (ClassCast): New class used to type cast objects into arbitrary
+       classes (used in Explicit Reference Conversions).
+
+       Implement `as' as well.
+
+       Reverted all the patches from Ravi below: they were broken:
+
+               * The use of `level' as a mechanism to stop recursive
+                 invocations is wrong.  That was there just to catch the
+                 bug with a strack trace but not as a way of addressing
+                 the problem.
+
+                 To fix the problem we have to *understand* what is going
+                 on and the interactions and come up with a plan, not
+                 just get things going.
+
+               * The use of the type conversion cache that I proposed
+                 last night had an open topic: How does this work across
+                 protection domains.  A user defined conversion might not
+                 be public in the location where we are applying the
+                 conversion, a different conversion might be selected
+                 (ie, private A->B (better) but public B->A (worse),
+                 inside A, A->B applies, but outside it, B->A will
+                 apply).
+
+               * On top of that (ie, even if the above is solved),
+                 conversions in a cache need to be abstract.  Ie, `To
+                 convert from an Int to a Short use an OpcodeCast', not
+                 `To convert from an Int to a Short use the OpcodeCast on
+                 the variable 5' (which is what this patch was doing).
+
+2001-09-28  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Invocation::ConversionExists): Re-write to use
+       the conversion cache
+
+       (Expression::ConvertImplicit): Automatic bailing out if level != 0. Also
+       cache all conversions done, not just user-defined ones.
+
+       (Invocation::BetterConversion): The real culprit. Use ConversionExists
+       to determine if a conversion exists instead of acutually trying to 
+       perform the conversion. It's faster too.
+
+       (Expression::ConvertExplicit): Modify to use ConversionExists to check
+       and only then attempt the implicit conversion.
+
+2001-09-28  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (ConvertImplicit): Use a cache for conversions
+       already found. Check level of recursion and bail out if necessary.
+
+2001-09-28  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (string_concat_string_string, string_concat_object_object):
+       Export standard methods that we expect for string operations.
+
+       * statement.cs (Block::UsageWarning): Track usage of variables and
+       report the errors for not used variables.
+
+       * expression.cs (Conditional::Resolve, ::Emit): Implement ?:
+       operator. 
+
+2001-09-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs: remove unnneded code 
+
+       * expression.cs: Removed BuiltinTypeAccess class
+
+       Fix the order in which implicit conversions are
+       done.  
+
+       The previous fixed dropped support for boxed conversions (adding a
+       test to the test suite now)
+
+       (UserImplicitCast::CanConvert): Remove test for source being null,
+       that code is broken.  We should not feed a null to begin with, if
+       we do, then we should track the bug where the problem originates
+       and not try to cover it up here.
+
+       Return a resolved expression of type UserImplicitCast on success
+       rather than true/false.  Ravi: this is what I was talking about,
+       the pattern is to use a static method as a "constructor" for
+       objects. 
+
+       Also, do not create arguments until the very last minute,
+       otherwise we always create the arguments even for lookups that
+       will never be performed. 
+
+       (UserImplicitCast::Resolve): Eliminate, objects of type
+       UserImplicitCast are born in a fully resolved state. 
+
+       * typemanager.cs (InitCoreTypes): Init also value_type
+       (System.ValueType). 
+
+       * expression.cs (Cast::Resolve): First resolve the child expression.
+
+       (LValue): Add new method AddressOf to be used by
+       the `&' operator.  
+
+       Change the argument of Store to take an EmitContext instead of an
+       ILGenerator, because things like FieldExpr need to be able to call
+       their children expression to generate the instance code. 
+
+       (Expression::Error, Expression::Warning): Sugar functions for
+       reporting errors.
+
+       (Expression::MemberLookup): Accept a TypeContainer instead of a
+       Report as the first argument.
+
+       (Expression::ResolvePrimary): Killed.  I still want to improve
+       this as currently the code is just not right.
+
+       (Expression::ResolveMemberAccess): Simplify, but it is still
+       wrong. 
+
+       (Unary::Resolve): Catch errors in AddressOf operators.
+
+       (LocalVariableReference::Emit, ::Store, ::AddressOf): typecast
+       index to a byte for the short-version, or the compiler will choose
+       the wrong Emit call, which generates the wrong data.
+
+       (ParameterReference::Emit, ::Store): same.
+
+       (FieldExpr::AddressOf): Implement.
+
+       * typemanager.cs: TypeManager: made public variable instead of
+       property.
+
+       * driver.cs: document --fatal.
+
+       * report.cs (ErrorMessage, WarningMessage): new names for the old
+       Error and Warning classes.
+
+       * cs-parser.jay (member_access): Turn built-in access to types
+       into a normal simplename
+
+2001-09-27  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Invocation::BetterConversion): Fix to cope
+       with q being null, since this was introducing a bug.
+
+       * expression.cs (ConvertImplicit): Do built-in conversions first.
+
+2001-09-27  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (UserImplicitCast::Resolve): Fix bug.
+
+2001-09-27  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer::AddConstructor): Fix a stupid bug
+       I had introduced long ago (what's new ?).
+
+       * expression.cs (UserImplicitCast::CanConvert): Static method to do 
+       the work of all the checking. 
+       (ConvertImplicit): Call CanConvert and only then create object if necessary.
+       (UserImplicitCast::CanConvert, ::Resolve): Re-write.
+
+       (Unary::Operator): Rename Add and Subtract to Addition and Subtraction because
+       that is the right way. 
+
+       (Invocation::MakeUnionSet): Convenience function to make unions of sets for 
+       overloading resolution. Use everywhere instead of cutting and pasting code.
+
+       (Binary::ResolveOperator): Use MakeUnionSet.
+
+       (UserImplicitCast::CanConvert, ::Resolve): Update to take care of the case when 
+       we have to convert to bool types. Not complete yet.
+
+2001-09-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (TypeManager::CSharpName): support ushort.
+
+       * expression.cs (Expression::TryImplicitIntConversion): Attempts
+       to provide an expression that performsn an implicit constant int
+       conversion (section 6.1.6).
+       (Expression::ConvertImplicitRequired): Reworked to include
+       implicit constant expression conversions.
+
+       (Expression::ConvertNumericExplicit): Finished.
+
+       (Invocation::Emit): If InstanceExpression is null, then it means
+       that we perform a call on this.
+
+2001-09-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Unary::Emit): Remove some dead code.
+       (Probe): Implement Resolve and Emit for `is'.
+       (Expression::ConvertImplicitRequired): Attempt to do constant
+       expression conversions here.  Maybe should be moved to
+       ConvertImplicit, but I am not sure.
+       (Expression::ImplicitLongConstantConversionPossible,
+       Expression::ImplicitIntConstantConversionPossible): New functions
+       that tell whether is it possible to apply an implicit constant
+       expression conversion.
+
+       (ConvertNumericExplicit): Started work on explicit numeric
+       conversions.
+
+       * cs-parser.jay: Update operator constants.
+
+       * parameter.cs (Parameters::GetParameterInfo): Hook up VerifyArgs
+       (Parameters::GetSignature): Hook up VerifyArgs here.
+       (Parameters::VerifyArgs): Verifies that no two arguments have the
+       same name. 
+
+       * class.cs (Operator): Update the operator names to reflect the
+       ones that the spec expects (as we are just stringizing the
+       operator names).
+
+       * expression.cs (Unary::ResolveOperator): Fix bug: Use
+       MethodInfo's ReturnType instead of LookupMethodByBuilder as the
+       previous usage did only work for our methods.
+       (Expression::ConvertImplicit): Handle decimal implicit numeric
+       conversions as well.
+       (Expression::InternalTypeConstructor): Used to invoke constructors
+       on internal types for default promotions.
+
+       (Unary::Emit): Implement special handling for the pre/post
+       increment/decrement for overloaded operators, as they need to have
+       the same semantics as the other operators.
+
+       (Binary::ResolveOperator): ditto.
+       (Invocation::ConversionExists): ditto.
+       (UserImplicitCast::Resolve): ditto.
+
+2001-09-26  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Unary::Emit and Binary::Emit): If we have an overloaded
+       operator, return after emitting body. Regression tests pass again !
+
+       * expression.cs (ConvertImplicit): Take TypeContainer as first argument
+       (Unary::ForceConversion, Binary::ForceConversion): Ditto.
+       (Invocation::OverloadResolve): Ditto.
+       (Invocation::BetterFunction, BetterConversion, ConversionExists): Ditto.
+
+       * everywhere : update calls to the above methods accordingly.
+
+2001-09-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs (Assign): Make it inherit from ExpressionStatement.
+
+       * expression.cs (ExpressionStatement): New base class used for
+       expressions that can appear in statements, so that we can provide
+       an alternate path to generate expression that do not leave a value
+       on the stack.
+
+       (Expression::Emit, and all the derivatives): We no longer return
+       whether a value is left on the stack or not.  Every expression
+       after being emitted leaves a single value on the stack.
+
+       * codegen.cs (EmitContext::EmitStatementExpression): Use the
+       facilties of ExpressionStatement if possible.
+
+       * cs-parser.jay: Update statement_expression.
+
+2001-09-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Change the wording of message
+
+2001-09-25  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Binary::ResolveOperator): Had forgottten to set 
+       the type of the expression to the return type of the method if
+       we have an overloaded operator match ! The regression tests pass again !
+       (Unary::ResolveOperator): Ditto.
+
+       * expression.cs (Invocation::ConversionExists): Correct the member lookup
+       to find "op_Implicit", not "implicit" ;-)
+       (UserImplicitCast): New class to take care of user-defined implicit conversions.
+       (ConvertImplicit, ForceConversion): Take TypeContainer argument
+
+       * everywhere : Correct calls to the above accordingly.
+
+       * expression.cs (UserImplicitCast::Resolve, ::Emit): Implement.
+       (ConvertImplicit): Do user-defined conversion if it exists.
+
+2001-09-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs: track location.
+       (Resolve): Use implicit conversions on assignment.
+
+       * literal.cs: Oops.  Not good, Emit of short access values should
+       pass (Bytes) or the wrong argument will be selected.
+
+       * expression.cs (Unary::Emit): Emit code for -expr.
+
+       (Unary::ResolveOperator): Handle `Substract' for non-constants
+       (substract from zero from the non-constants).
+       Deal with Doubles as well. 
+
+       (Expression::ConvertImplicitRequired): New routine that reports an
+       error if no implicit conversion exists. 
+
+       (Invocation::OverloadResolve): Store the converted implicit
+       expressions if we make them
+
+2001-09-24  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (ConstructorInitializer): Take a Location argument.
+       (ConstructorBaseInitializer): Same here.
+       (ConstructorThisInitializer): Same here.
+
+       * cs-parser.jay : Update all calls accordingly.
+
+       * expression.cs (Unary, Binary, New): Take location argument.
+       Update accordingly everywhere.
+
+       * cs-parser.jay : Update all calls to the above to take a location
+       argument.
+
+       * class.cs : Ditto.
+
+2001-09-24  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Invocation::BetterFunction): Take TypeContainer argument
+       (Invocation::BetterConversion): Same here
+       (Invocation::ConversionExists): Ditto.
+
+       (Invocation::ConversionExists): Implement.
+
+2001-09-22  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (OverloadResolve): Improve some more to catch errors 1502 and 1503
+       Also take an additional TypeContainer argument.
+
+       * All over : Pass in TypeContainer as argument to OverloadResolve.
+
+       * typemanager.cs (CSharpName): Update to check for the string type and return
+       that too.
+
+       * expression.cs (Invocation::FullMethodDesc): New static method to return a string fully describing
+       a given method.
+
+2001-09-21  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Invocation::OverloadResolve): Re-write to conform more to the spec.
+       (Invocation::BetterFunction): Implement.
+       (Invocation::BetterConversion): Implement.
+       (Invocation::ConversionExists): Skeleton, no implementation yet.
+
+       Okay, things work fine !
+
+2001-09-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs: declare and load enum_type, delegate_type and
+       void_type. 
+
+       * expression.cs (Expression::Emit): Now emit returns a value that
+       tells whether a value is left on the stack or not.  This strategy
+       might be reveted tomorrow with a mechanism that would address
+       multiple assignments.
+       (Expression::report118): Utility routine to report mismatches on
+       the ExprClass.
+
+       (Unary::Report23): Report impossible type/operator combination
+       utility function.
+
+       (Unary::IsIncrementableNumber): Whether the type can be
+       incremented or decremented with add.
+       (Unary::ResolveOperator): Also allow enumerations to be bitwise
+       complemented. 
+       (Unary::ResolveOperator): Implement ++, !, ~,
+
+       (Invocation::Emit): Deal with new Emit convetion.
+
+       * All Expression derivatives: Updated their Emit method to return
+       whether they leave values on the stack or not.
+
+       * codegen.cs (CodeGen::EmitStatement): Pop values left on the
+       stack for expressions that are statements. 
+
+2001-09-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (LValue): New interface.  Must be implemented by
+       LValue objects.
+       (LocalVariableReference, ParameterReference, FieldExpr): Implement
+       LValue interface.
+
+       * assign.cs (Assign::Emit, Assign::Resolve): Use new LValue
+       interface for generating code, simplifies the code.
+
+2001-09-20  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (everywhere): Comment out return statements in ::Resolve
+       methods to avoid the warnings.
+
+2001-09-20  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs (parse): Report error 2001 if we can not open the
+       source file.
+
+       * expression.cs (SimpleName::ResolveSimpleName): Error if we can
+       not resolve it.
+
+       * cs-parser.jay (QualifierIdentifier): Pass location to SimpleName
+       object. 
+
+       * statement.cs (Block::EmitMeta): Reuse the count across all the variables,
+       otherwise nested blocks end up with the same index.
+
+       * codegen.cs (CodeGen::EmitTopBlock): Pass initial sequence
+
+       * expression.cs:  Instead of having FIXMEs in the Resolve
+       functions, throw exceptions so it is obvious that we are facing a
+       bug. 
+
+       * cs-parser.jay (invocation_expression): Pass Location information.
+
+       * codegen.cs (CodeGen::Save, CodeGen::CodeGen, CodeGen::Basename):
+       Use a basename for those routines because .NET does not like paths
+       on them. 
+
+       * class.cs (TypeContainer::AddMethod): Do not call DefineName if the name was
+       already defined.
+
+2001-09-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (TypeManager::CoreLookupType): A function to make sure that we
+       are loading the correct data types (throws an exception if not).
+       (TypeManager::InitCoreTypes): Use CoreLookupType
+
+       * expression.cs (Unary::ResolveOperator): return the child
+       expression for expressions which are just +expr.
+       (Unary::ResolveOperator): Return negative literals for -LITERAL
+       expressions (otherwise they are Unary {Literal}).
+       (Invocation::Badness): Take into account `Implicit constant
+       expression conversions'.
+
+       * literal.cs (LongLiteral): Implement long literal class.
+       (IntLiteral): export the `Value' of the intliteral. 
+
+2001-09-19  Ravi Pratap  <ravi@ximian.com>
+
+       * expression.cs (Binary::Emit): Finally get the emission right ! Woo!
+
+       * class.cs (Operator::Define): Change the methodname prefix to 'op_' 
+       instead of 'Operator'
+
+       * expression.cs (Binary::ResolveOperator): Update accordingly.
+       (Unary::Operator): Change names to 'Add' and 'Subtract' instead 'Plus'
+       and 'Minus'
+
+       * cs-parser.jay (unary_expression): Update to use the new names.
+
+       * gen-treedump.cs (GetUnary): Same here.
+
+       * expression.cs (Unary::Resolve): Implement.
+       (Binary::ResolveOperator): Re-write bits to quietly continue if no overloaded 
+       operators are found instead of making noise ;-)
+       (Unary::ResolveOperator): New method to do precisely the same thing which
+       Binary::ResolveOperator does for Binary expressions.
+       (Unary.method, .Arguments): Add.
+       (Unary::OperName): Implement.   
+       (Unary::ForceConversion): Copy and Paste !
+
+       * class.cs (Operator::Define): Fix a small bug for the case when we have 
+       a unary operator.
+
+       * expression.cs (Unary::Emit): Implement. Need to find the right Opcodes
+       for the inbuilt operators. Only overloading works for now ;-)
+
+2001-09-18  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (CheckedExpr::Resolve, CheckedExpr::Emit,
+       UnCheckedExpr::Resolve, UnCheckedExpr::Emit): Implement.
+
+       * expression.cs (This::Emit): Implement. 
+       (This::Resolve): Implement.
+       (TypeOf:Resolve): Implement.
+       (Expression::ResolveSimpleName): Add an implicit this to instance
+       field references. 
+       (MemberAccess::Resolve): Deal with Parameters and Fields. 
+       Bind instance variable to Field expressions.
+       (FieldExpr::Instance): New field used to track the expression that
+       represents the object instance.
+       (FieldExpr::Resolve): Track potential errors from MemberLookup not
+       binding 
+       (FieldExpr::Emit): Implement.
+
+       * codegen.cs (EmitIf, EmitStatement, EmitBlock): Propagate whether
+       the last instruction contains a return opcode to avoid generating
+       the last `ret' instruction (this generates correct code, and it is
+       nice to pass the peverify output).
+
+       * class.cs (TypeContainer::EmitFieldInitializers): Implement field
+       initializer for static and instance variables.
+       (Constructor::Emit): Allow initializer to be null in the case of
+       static constructors.  Only emit initializer for instance
+       constructors. 
+
+       (TypeContainer::FindMembers): Return a null array if there are no
+       matches.
+
+       Also fix the code for the MemberTypes.Method branch, as it was not
+       scanning that for operators (or tried to access null variables before).
+
+       * assign.cs (Assign::Emit): Handle instance and static fields. 
+
+       * TODO: Updated.
+
+       * driver.cs: Stop compilation if there are parse errors.
+
+       * cs-parser.jay (constructor_declaration): Provide default base
+       initializer for non-static constructors.
+       (constructor_declarator): Do not provide a default base
+       initializers if none was specified.
+       Catch the fact that constructors should not have parameters.
+
+       * class.cs: Do not emit parent class initializers for static
+       constructors, that should be flagged as an error.
+
+2001-09-18  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (RegisterMethodBuilder): Remove : it's unnecessary.
+       Move back code into TypeContainer::Populate.
+
+2001-09-18  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer::AddConstructor): Fix the check to
+       compare against Name, not Basename. 
+       (Operator::OpType): Change Plus and Minus to Add and Subtract.
+
+       * cs-parser.jay : Update accordingly.
+
+       * class.cs (TypeContainer::FindMembers): For the case where we are searching
+       for methods, don't forget to look into the operators too.
+       (RegisterMethodBuilder): Helper method to take care of this for
+       methods, constructors and operators.
+       (Operator::Define): Completely revamp.
+       (Operator.OperatorMethod, MethodName): New fields.
+       (TypeContainer::Populate): Move the registering of builders into
+       RegisterMethodBuilder.
+       (Operator::Emit): Re-write.
+
+       * expression.cs (Binary::Emit): Comment out code path to emit method
+       invocation stuff for the case when we have a user defined operator. I am
+       just not able to get it right !
+
+2001-09-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Expression::OverloadResolve): Drop TypeContainer
+       argument. 
+
+       (Expression::MemberLookup): Provide a version that allows to
+       specify the MemberTypes and BindingFlags. 
+
+       * statement.cs (Block::GetVariableInfo): Forgot to recurse here,
+       so it was not fetching variable information from outer blocks.
+
+       * modifiers.cs: (Modifiers::TypeAttr): Invert condition on
+       Beforefieldinit as it was buggy.
+
+       * rootcontext.cs (::LookupInterfaceOrClass): Removed an Error -200
+       that Ravi put here.  
+
+       * class.cs (Constructor::Emit): Only emit if block is not null.
+       (TypeContainer::EmitDefaultConstructor): Removed routine, now we
+       deal with this by semantically definining it as if the user had
+       done it.
+
+       (TypeContainer::FindMembers): Removed ad-hoc hack to deal with
+       constructors as we now "emit" them at a higher level.
+
+       (TypeContainer::DefineDefaultConstructor): Used to define the
+       default constructors if none was provided.
+
+       (ConstructorInitializer): Add methods Resolve and Emit. 
+
+       * expression.cs: Cast to ConstructorInfo instead of MethodInfo
+
+2001-09-17  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer::EmitDefaultConstructor): Register
+       the default constructor builder with our hashtable for methodbuilders
+       to methodcores.
+
+       * expression.cs (Invocation::OverloadResolve): Add a check for pd == null
+       and argument_count is 0 in which case we have a match.
+       (Binary::ResolveOperator): More null checking and miscellaneous coding
+       style cleanup.
+
+2001-09-17  Ravi Pratap  <ravi@ximian.com>
+
+       * rootcontext.cs (IsNameSpace): Compare against null.
+
+       * everywhere : Correct spelling to 'Greater' and to 'Subtract'
+
+       * class.cs (Operator::OpType): Change names to match the ones in Binary::Operator
+       and Unary::Operator.
+
+       * cs-parser.jay (operator_declaration, CheckBinaryOperator, CheckUnaryOperator): Update
+       accordingly.
+
+       * expression.cs (Binary::method): New member to hold the MethodBase for the case when
+       we have overloaded operators.
+       (Binary::ResolveOperator): Implement the part which does the operator overload
+       resolution.
+
+       * class.cs (Operator::Emit): Implement.
+       (TypeContainer::Emit): Emit the operators we have too.
+
+       * expression.cs (Binary::Emit): Update to emit the appropriate code for
+       the case when we have a user-defined operator.
+
+2001-09-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs: Fix bug: tree.Namespaces might be null.
+
+2001-09-16  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (EmitStaticFieldInitializers, EmitFieldInitializers): Make public.
+       (TypeContainer::EmitConstructor): Remove and move code into Contructor::Emit.
+       (Constructor::Emit): Implement.
+       (EmitStaticFieldInitializers, EmitFieldInitializers): Ensure we return immediately
+       if we have no work to do. 
+       (TypeContainer::Emit): Pass in TypeContainer as argument to the constructor's 
+       Emit method.
+
+       * interface.cs (Interface::InterfaceAttr): Re-write to be more correct and complete.
+       (Interface::IsTopLevel): Add. Same as TypeContainer::IsTopLevel.
+
+       * class.cs (TypeContainer::IsTopLevel): Modify to use parent.Parent instead
+       of parent.parent.
+
+2001-09-15  Ravi Pratap  <ravi@ximian.com>
+
+       * tree.cs (Tree::namespaces): New hashtable to keep track of namespaces
+       in the source.
+       (Tree::RecordNamespace): Method to do what the name says ;-)
+       (Tree::Namespaces): Property to get at the namespaces hashtable.
+
+       * cs-parser.jay (namespace_declaration): Call RecordNamespace to 
+       keep track.
+
+       * rootcontext.cs (IsNamespace): Fixed it :-)
+
+2001-09-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer::FindMembers): Add support for
+       constructors. 
+       (MethodCore): New class that encapsulates both the shared aspects
+       of a Constructor and a Method.  
+       (Method, Constructor): Factored pieces into MethodCore.
+
+       * driver.cs: Added --fatal which makes errors throw exceptions.
+       Load System assembly as well as part of the standard library.
+
+       * report.cs: Allow throwing exceptions on errors for debugging.
+
+       * modifiers.cs: Do not use `parent', instead use the real type
+       container to evaluate permission settings.
+
+       * class.cs: Put Ravi's patch back in.  He is right, and we will
+       have to cope with the
+
+2001-09-14  Ravi Pratap  <ravi@ximian.com>
+
+       * modifiers.cs (TypeAttr, MethodAttr, FieldAttr): Map protected internal to
+       FamORAssem, not FamANDAssem.
+
+2001-09-14  Miguel de Icaza  <miguel@ximian.com>
+
+       * driver.cs: Added --parse option that only parses its input files
+       and terminates.
+
+       * class.cs: Reverted last change from Ravi to IsTopLevel.  That is
+       incorrect.  IsTopLevel is not used to tell whether an object is
+       root_types or not (that can be achieved by testing this ==
+       root_types).  But to see if this is a top-level *class* (not
+       necessarly our "toplevel" container). 
+
+2001-09-14  Ravi Pratap  <ravi@ximian.com>
+
+       * enum.cs (Enum::Define): Modify to call the Lookup method on the
+       parent instead of a direct call to GetType.
+
+2001-09-14  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer::TypeAttr): Remove property code and move it into
+       Modifiers.TypeAttr. This should just be a call to that method.
+
+       * modifiers.cs (TypeAttr): Re-write and take an extra argument, the TypeContainer
+       object so that we can determine if we are top-level or not.
+
+       * delegate.cs (Delegate::Define): Update call to TypeAttr method to pass in the 
+       TypeContainer too.
+
+       * enum.cs (Enum::Define): Ditto.
+
+       * modifiers.cs (FieldAttr): Re-write.
+
+       * class.cs (TypeContainer::IsTopLevel): Change accessibility to public.
+       (TypeContainer::HaveStaticConstructor): New property to provide access
+       to precisely that info.
+
+       * modifiers.cs (MethodAttr): Re-write.
+       (EventAttr): Remove altogether as there seems to be no ostensible use for it.
+
+       * class.cs (TypeContainer::IsTopLevel): Re-write. root_types doesn't seem to be the parent
+       of top-level types as claimed.
+
+2001-09-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (MemberLookup): Fruitless attempt to lookup
+       constructors.  Maybe I need to emit default constructors?  That
+       might be it (currently .NET emits this for me automatically).
+       (Invocation::OverloadResolve): Cope with Arguments == null.
+       (Invocation::EmitArguments): new function, shared by the new
+       constructor and us.
+       (Invocation::Emit): Handle static and instance methods.  Emit
+       proper call instruction for virtual or non-virtual invocations.
+       (New::Emit): Implement.
+       (New::Resolve): Implement.
+       (MemberAccess:Resolve): Implement.
+       (MethodGroupExpr::InstanceExpression): used conforming to the spec
+       to track instances.
+       (FieldExpr::Resolve): Set type.
+
+       * support.cs: Handle empty arguments.
+               
+       * cs-parser.jay (CompositeLookup, QualifierIdentifier,
+       SimpleLookup): Auxiliary routines to help parse a qualifier
+       identifier.  
+
+       Update qualifier_identifier rule.
+
+       * codegen.cs: Removed debugging messages.
+
+       * class.cs: Make this a global thing, this acts just as a "key" to
+       objects that we might have around.
+
+       (Populate): Only initialize method_builders_to_methods once.
+
+       * expression.cs (PropertyExpr): Initialize type from the
+       PropertyType. 
+
+       * codegen.cs (EmitContext::EmitBoolExpression): Use propper
+       Resolve pattern.  Attempt to implicitly convert value to boolean.
+       Emit code.
+
+       * expression.cs: Set the type for the int32/int32 argument case.
+       (Binary::ResolveOperator): Set the return type to boolean for
+       comparission operators
+
+       * typemanager.cs: Remove debugging print code.
+
+       (Invocation::Resolve): resolve type.
+
+       * class.cs: Allocate a MemberInfo of the correct size, as the code
+       elsewhere depends on the test to reflect the correct contents.
+
+       (Method::) Keep track of parameters, due to System.Reflection holes
+
+       (TypeContainer::Populate): Keep track of MethodBuilders to Method
+       mapping here.
+
+       (TypeContainer::FindMembers): Use ArrayList and then copy an array
+       of the exact size and return that.
+
+       (Class::LookupMethodByBuilder): New function that maps
+       MethodBuilders to its methods.  Required to locate the information
+       on methods because System.Reflection bit us again.
+
+       * support.cs: New file, contains an interface ParameterData and
+       two implementations: ReflectionParameters and InternalParameters
+       used to access Parameter information.  We will need to grow this
+       as required.
+
+       * expression.cs (Invocation::GetParameterData): implement a cache
+       and a wrapper around the ParameterData creation for methods. 
+       (Invocation::OverloadResolve): Use new code.
+
+2001-09-13  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer::EmitField): Remove and move into 
+       (Field::Define): here and modify accordingly.
+       (Field.FieldBuilder): New member.
+       (TypeContainer::Populate): Update accordingly.
+       (TypeContainer::FindMembers): Implement.
+
+2001-09-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs: (VariableInfo::VariableType): New field to be
+       initialized with the full type once it is resolved. 
+
+2001-09-12  Miguel de Icaza  <miguel@ximian.com>
+
+       * parameter.cs (GetParameterInfo): Use a type cache to compute
+       things only once, and to reuse this information
+
+       * expression.cs (LocalVariableReference::Emit): Implement.
+       (OpcodeCast::Emit): fix.
+
+       (ParameterReference::Resolve): Implement.
+       (ParameterReference::Emit): Implement.
+
+       * cs-parser.jay: Fix bug introduced by Ravi, variable initializers
+       that are expressions need to stay as Expressions.
+
+       * typemanager.cs (CSharpName): Returns the C# name of a type if
+       possible. 
+
+       * expression.cs (Expression::ConvertImplicit): New function that
+       implements implicit type conversions.
+
+       (Expression::ImplicitReferenceConversion): Implements implicit
+       reference conversions.
+
+       (EmptyCast): New type for transparent casts.
+
+       (OpcodeCast): New type for casts of types that are performed with
+       a sequence of bytecodes.
+
+       (BoxedCast): New type used for casting value types into reference
+       types.  Emits a box opcode.
+
+       (Binary::DoNumericPromotions): Implements numeric promotions of
+       and computation of the Binary::Type.
+
+       (Binary::EmitBranchable): Optimization.
+
+       (Binary::Emit): Implement code emission for expressions.
+
+       * typemanager.cs (TypeManager): Added two new core types: sbyte
+       and byte.
+
+2001-09-12  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer::FindMembers): Method which does exactly
+       what Type.FindMembers does, only we don't have to use reflection. No
+       implementation yet.
+
+       * typemanager.cs (typecontainers): New hashtable to hold the corresponding
+       typecontainer objects as we need to get at them.
+       (TypeManager::AddUserType): Overload to take an extra argument, the TypeContainer.
+
+       * rootcontext.cs : Correspondingly modify called to AddUserType to pass the
+       typecontainer object.
+
+       * expression.cs (MemberLookup): Modify signature to take a RootContext object instead
+       of just a Report object.
+
+2001-09-11  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Event::Define): Go back to using the prefixes "add_" and
+       "remove_"
+       (TypeContainer::Populate): Now define the delegates of the type too.
+       (TypeContainer.Delegates): Property to access the list of delegates defined
+       in the type.
+
+       * delegates.cs (Delegate::Define): Implement partially.
+
+       * modifiers.cs (TypeAttr): Handle more flags.
+
+2001-09-11  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Indexer::Define): Fix for loop iteration condition to be just <
+       and not <=
+       (Operator::Define): Re-write logic to get types by using the LookupType method
+       instead of blindly doing a Type.GetType ! How stupid can I get ;-) ?
+       (Indexer::Define): Ditto.
+       (Event::Define): Ditto.
+       (Property::Define): Ditto.
+
+2001-09-10  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer::Populate): Now define operators too. 
+       (TypeContainer.Operators): New property to access the list of operators
+       in a type.
+       (Operator.OperatorMethodBuilder): New member to hold the method builder
+       for the operator we are defining.
+       (Operator::Define): Implement.
+
+2001-09-10  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Event::Define): Make the prefixes of the accessor methods
+       addOn_ and removeOn_ 
+
+       * genericparser.cs (GenericParser::error): Overloaded method to handle the case
+       of the location being passed in too. Ideally, this should go later since all
+       error reporting should be done through the Report object.
+
+       * class.cs (TypeContainer.Indexers): New property to access the list of indexers.
+       (Populate): Iterate thru the indexers we have and define them too.
+       (Indexer.GetMethodBuilder, .SetMethodBuilder): New members to hold the method builders
+       for the get and set accessors.
+       (Indexer::Define): Implement.
+
+2001-09-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (Binary::Resolve): Beginning of it.  I scratched
+       my previous implementation, did not work.
+
+       * typemanager.cs: Add a couple of missing types (the longs).
+
+       * literal.cs: Use TypeManager.bool_type instead of getting it.
+
+       * expression.cs (EventExpr): New kind of expressions.
+       (Expressio::ExprClassFromMemberInfo): finish
+
+2001-09-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * assign.cs: Emit stores to static fields differently.
+
+2001-09-08  Ravi Pratap  <ravi@ximian.com>
+
+       * Merge in changes and adjust code to tackle conflicts. Backed out my
+       code in Assign::Resolve ;-) 
+
+2001-09-08  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (CheckAttributeTarget): Modify call to error to use
+       instead Report.Error and also pass in the location.
+       (CSharpParser::Lexer): New readonly property to return the reference
+       to the Tokenizer object.
+       (declare_local_variables): Use Report.Error with location instead of plain 
+       old error.
+       (CheckDef): Ditto.
+
+       * class.cs (Operator::CheckUnaryOperator): Move into cs-parser.jay.
+       (Operator.CheckBinaryOperator): Ditto.
+
+       * cs-parser.jay (operator_declarator): Update accordingly.
+
+       * cs-parser.jay (CheckUnaryOperator): Modify to use Report.Error
+       (CheckBinaryOperator): Same here.
+
+       * rootcontext.cs (LookupType): Add an extra lookup which simply does a lookup
+       on the name without any prefixes of namespace names etc. This is because we
+       already might have something already fully qualified like 
+       'System.Console.WriteLine'
+
+       * assign.cs (Resolve): Begin implementation. Stuck ;-)
+
+2001-09-07  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-tokenizer.cs (location): Return a string which also contains
+       the file name.
+
+       * expression.cs (ElementAccess): New class for expressions of the
+       type 'element access.'
+       (BaseAccess): New class for expressions of the type 'base access.'
+       (CheckedExpr, UnCheckedExpr): New classes for Checked and Unchecked expressions
+       respectively.
+
+       * cs-parser.jay (element_access): Implement action.
+       (base_access): Implement actions.
+       (checked_expression, unchecked_expression): Implement.
+
+       * cs-parser.jay (local_variable_type): Correct and implement.
+       (type_suffixes, type_suffix_list, type_suffix): Implement actions.
+
+       * cs-tokenizer.cs (real_type_suffix): Comment out the extra getchar.
+
+       * cs-parser.jay (rank_specifiers): Remove space while concatenating the type's
+       name and the specifiers.
+
+       * interface.cs (InterfaceAttr): New property to return the corresponding TypeAttributes
+
+       * rootcontext.cs (CreateInterface): Use the InterfaceAttr property instead of 
+       making them all public ;-)
+
+       * cs-parser.jay (error): Remove entirely as we have an implementation in the base
+       class anyways.
+
+2001-09-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * expression.cs (ExprClassFromMemberInfo): Return FieldExpr and
+       PropertyExprs.
+       (FieldExpr, PropertyExprs): New resolved expressions.
+       (SimpleName::MemberStaticCheck): Perform static checks for access
+       to non-static fields on static methods. Maybe this should be
+       generalized for MemberAccesses. 
+       (SimpleName::ResolveSimpleName): More work on simple name
+       resolution. 
+
+       * cs-parser.jay (primary_expression/qualified_identifier): track
+       the parameter index.
+
+       * codegen.cs (CodeGen::Save): Catch save exception, report error.
+       (EmitContext::EmitBoolExpression): Chain to expression generation
+       instead of temporary hack.
+       (::EmitStatementExpression): Put generic expression code generation.
+
+       * assign.cs (Assign::Emit): Implement variable assignments to
+       local variables, parameters and fields.
+
+2001-09-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs (Block::GetVariableInfo): New method, returns the
+       VariableInfo for a variable name in a block.
+       (Block::GetVariableType): Implement in terms of GetVariableInfo
+
+       * literal.cs (IntLiteral::Emit, FloatLiteral::Emit,
+       DoubleLiteral::Emit, CharLiteral::Emit, BoolLiteral::Emit): Implement
+
+2001-09-06  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (operator_declaration): Continue on my quest : update
+       to take attributes argument.
+       (event_declaration): Ditto.
+       (enum_declaration): Ditto.
+       (indexer_declaration): Ditto.
+
+       * class.cs (Operator::Operator): Update constructor accordingly.
+       (Event::Event): Ditto.
+
+       * delegate.cs (Delegate::Delegate): Same here.
+
+       * enum.cs (Enum::Enum): Same here.
+
+2001-09-05  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (CheckAttributeTarget): Update to use the right error number.
+
+       * ../tests/cs0658.cs : New file to demonstrate error 0658.
+
+       * attribute.cs (Attributes): New class to encapsulate all attributes which were
+       being passed around as an arraylist.
+       (Attributes::AddAttribute): Method to add attribute sections.
+
+       * cs-parser.jay (opt_attributes): Modify actions to use the new Attributes class.
+       (struct_declaration): Update accordingly.
+       (constant_declaration): Update.
+       (field_declaration): Update.
+       (method_header): Update.
+       (fixed_parameter): Update.
+       (parameter_array): Ditto.
+       (property_declaration): Ditto.
+       (destructor_declaration): Ditto.
+
+       * class.cs (Struct::Struct): Update constructors accordingly.
+       (Class::Class): Ditto.
+       (Field::Field): Ditto.
+       (Method::Method): Ditto.
+       (Property::Property): Ditto.
+       (TypeContainer::OptAttribute): update property's return type.
+
+       * interface.cs (Interface.opt_attributes): New member.
+       (Interface::Interface): Update to take the extra Attributes argument.
+
+       * parameter.cs (Parameter::Parameter): Ditto.
+
+       * constant.cs (Constant::Constant): Ditto.
+
+       * interface.cs (InterfaceMemberBase): New OptAttributes field.
+       (InterfaceMemberBase::InterfaceMemberBase): Update constructor to take 
+       the attributes as a parameter.
+       (InterfaceProperty): Update constructor call.
+       (InterfaceEvent): Ditto.
+       (InterfaceMethod): Ditto.
+       (InterfaceIndexer): Ditto.
+
+       * cs-parser.jay (interface_indexer_declaration): Update call to constructor to 
+       pass the attributes too.
+       (interface_event_declaration): Ditto.
+       (interface_property_declaration): Ditto.
+       (interface_method_declaration): Ditto.
+       (interface_declaration): Ditto.
+
+2001-09-05  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (Method::Define): Track the "static Main" definition to
+       create an entry point. 
+
+       * rootcontext.cs (RootContext::EntryPoint): MethodInfo that holds the
+       EntryPoint if we find it. 
+
+       * codegen.cs (EmitContext::EmitInvocation): Emit invocations.
+       (EmitContext::ig): Make this variable public.
+
+       * driver.cs: Make the default output file be the first file name
+       with the .exe extension.  
+
+       Detect empty compilations
+
+       Handle various kinds of output targets.  Handle --target and
+       rename -t to --dumper.
+
+       * expression.cs, literal.cs, assign.cs, constant.cs: All `Resolve'
+       methods inherited from Expression return now an Expression.  This
+       will is used during the tree rewriting as we resolve them during
+       semantic analysis.
+
+       (Expression::MemberLookup): Implements the MemberLookup (7.3) from
+       the spec.  Missing entirely is the information about
+       accessability of elements of it.
+
+       (Expression::ExprClassFromMemberInfo): New constructor for
+       Expressions that creates a fully initialized Expression based on
+       a MemberInfo that is one of Eventinfo, FieldINfo, PropertyInfo or
+       a Type.
+
+       (Invocation::Resolve): Begin implementing resolution of invocations.
+
+       * literal.cs (StringLiteral):  Implement Emit.
+
+2001-09-05  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (error): Add new modifier because we are hiding an inherited
+       member.
+
+2001-09-04  Ravi Pratap  <ravi@ximian.com>
+
+       * cs-parser.jay (attribute_arguments): Implement actions.
+       (attribute): Fix bug in production. Implement action.
+       (attribute_list): Implement.
+       (attribute_target): Implement.
+       (attribute_target_specifier, opt_target_specifier): Implement
+       (CheckAttributeTarget): New method to check if the attribute target
+       is valid.
+       (attribute_section): Implement.
+       (opt_attributes): Implement.
+
+       * attribute.cs : New file to handle attributes.
+       (Attribute): Class to hold attribute info.
+
+       * cs-parser.jay (opt_attribute_target_specifier): Remove production
+       (attribute_section): Modify production to use 2 different rules to 
+       achieve the same thing. 1 s/r conflict down !
+       Clean out commented, useless, non-reducing dimension_separator rules.
+
+       * class.cs (TypeContainer.attributes): New member to hold list
+       of attributes for a type.
+       (Struct::Struct): Modify to take one more argument, the attribute list.
+       (Class::Class): Ditto.
+       (Field::Field): Ditto.
+       (Method::Method): Ditto.
+       (Property::Property): Ditto.
+
+       * cs-parser.jay (struct_declaration): Update constructor call to
+       pass in the attributes too.
+       (class_declaration): Ditto.
+       (constant_declaration): Ditto.
+       (field_declaration): Ditto.
+       (method_header): Ditto.
+       (fixed_parameter): Ditto.
+       (parameter_array): Ditto.
+       (property_declaration): Ditto.
+
+       * constant.cs (Constant::Constant): Update constructor similarly.
+       Use System.Collections.
+
+       * parameter.cs (Parameter::Parameter): Update as above.
+
+2001-09-02  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (TypeContainer::AddDelegate): New method to add a delegate.
+       (TypeContainer.delegates): New member to hold list of delegates.
+
+       * cs-parser.jay (delegate_declaration): Implement the action correctly 
+       this time as I seem to be on crack ;-)
+
+2001-09-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs (RootContext::IsNamespace): new function, used to
+       tell whether an identifier represents a namespace.
+
+       * expression.cs (NamespaceExpr): A namespace expression, used only
+       temporarly during expression resolution.
+       (Expression::ResolveSimpleName, ::ResolvePrimary, ::ResolveName):
+       utility functions to resolve names on expressions.
+
+2001-09-01  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs: Add hook for StatementExpressions. 
+
+       * class.cs: Fix inverted test for static flag in methods.
+
+2001-09-02  Ravi Pratap  <ravi@ximian.com>
+
+       * class.cs (Operator::CheckUnaryOperator): Correct error number used
+       to make it coincide with MS' number.
+       (Operator::CheckBinaryOperator): Ditto.
+
+       * ../errors/errors.txt : Remove error numbers added earlier.
+
+       * ../errors/cs1019.cs : Test case for error # 1019
+
+       * ../errros/cs1020.cs : Test case for error # 1020
+
+       * cs-parser.jay : Clean out commented cruft.
+       (dimension_separators, dimension_separator): Comment out. Ostensibly not
+       used anywhere - non-reducing rule.
+       (namespace_declarations): Non-reducing rule - comment out.
+
+       * enum.cs (Enum::AddEnum): Rename to AddEnumMember as I was getting confused
+       with TypeContainer::AddEnum.
+
+       * delegate.cs : New file for delegate handling classes.
+       (Delegate): Class for declaring delegates.
+
+       * makefile : Update.
+
+       * cs-parser.jay (delegate_declaration): Implement.
+
+2001-09-01  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * class.cs (Event::Define): Implement.
+       (Event.EventBuilder): New member.
+
+       * class.cs (TypeContainer::Populate): Update to define all enums and events
+       we have.
+       (Events): New property for the events arraylist we hold. Shouldn't we move to using
+       readonly fields for all these cases ?
+
+2001-08-31  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * class.cs (Property): Revamp to use the convention of making fields readonly.
+       Accordingly modify code elsewhere.
+
+       * class.cs : Apply patch from Mr. Mandar <go_mono@hotmail.com> for implementing
+       the Define method of the Property class.
+
+       * class.cs : Clean up applied patch and update references to variables etc. Fix 
+       trivial bug.
+       (TypeContainer::Populate): Update to define all the properties we have. Also
+       define all enumerations.
+
+       * enum.cs (Define): Implement.
+
+2001-08-31  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * cs-parser.jay (overloadable_operator): The semantic value is an
+       enum of the Operator class.
+       (operator_declarator): Implement actions.
+       (operator_declaration): Implement.
+
+       * class.cs (Operator::CheckUnaryOperator): New static method to help in checking
+       validity of definitions.
+       (Operator::CheckBinaryOperator): Static method to check for binary operators
+       (TypeContainer::AddOperator): New method to add an operator to a type.
+
+       * cs-parser.jay (indexer_declaration): Added line to actually call the
+       AddIndexer method so it gets added ;-)
+
+       * ../errors/errors.txt : Update to include new error numbers. Are these numbers 
+       already taken care of by the MS compiler ?  
+
+2001-08-29  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * class.cs (Operator): New class for operator declarations.
+       (Operator::OpType): Enum for the various operators.
+
+2001-08-29  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * class.cs (TypeContainer::AddIndexer): Remove FIXME comment. We
+       ostensibly handle this in semantic analysis.
+
+       * cs-parser.jay (general_catch_clause): Comment out
+       (specific_catch_clauses, specific_catch_clause): Ditto.
+       (opt_general_catch_clause, opt_specific_catch_clauses): Ditto
+       (catch_args, opt_catch_args): New productions.
+       (catch_clause): Rewrite to use the new productions above
+       (catch_clauses): Modify accordingly.
+       (opt_catch_clauses): New production to use in try_statement
+       (try_statement): Revamp. Basically, we get rid of one unnecessary rule
+       and re-write the code in the actions to extract the specific and
+       general catch clauses by being a little smart ;-)
+
+       * ../tests/try.cs : Fix. It's not 'finalize' my friend, it's 'finally' !
+       Hooray, try and catch statements parse fine !
+
+2001-08-28  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * statement.cs (Block::GetVariableType): Fix logic to extract the type
+       string from the hashtable of variables.
+
+       * cs-parser.jay (event_accessor_declarations): Trivial fix. Man, how did
+       I end up making that mistake ;-)
+       (catch_clauses): Fixed gross error which made Key and Value of the 
+       DictionaryEntry the same : $1 !!
+
+2001-08-28  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * cs-tokenizer.cs (initTokens): Add keywords 'add' and 'remove'
+
+       * cs-parser.jay (event_declaration): Correct to remove the semicolon
+       when the add and remove accessors are specified. 
+
+2001-08-28  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * cs-parser.jay (IndexerDeclaration): New helper class to hold
+       information about indexer_declarator.
+       (indexer_declarator): Implement actions.
+       (parsing_indexer): New local boolean used to keep track of whether
+       we are parsing indexers or properties. This is necessary because 
+       implicit_parameters come into picture even for the get accessor in the 
+       case of an indexer.
+       (get_accessor_declaration, set_accessor_declaration): Correspondingly modified.
+
+       * class.cs (Indexer): New class for indexer declarations.
+       (TypeContainer::AddIndexer): New method to add an indexer to a type.
+       (TypeContainer::indexers): New member to hold list of indexers for the
+       type.
+
+2001-08-27  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * cs-parser.jay (add_accessor_declaration): Implement action.
+       (remove_accessor_declaration): Implement action.
+       (event_accessors_declaration): Implement
+       (variable_declarators): swap statements for first rule - trivial.
+
+       * class.cs (Event): New class to hold information about event
+       declarations.
+       (TypeContainer::AddEvent): New method to add an event to a type
+       (TypeContainer::events): New member to hold list of events.
+
+       * cs-parser.jay (event_declaration): Implement actions.
+
+2001-08-27  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * cs-parser.jay (dim_separators): Implement. Make it a string
+       concatenating all the commas together, just as they appear.
+       (opt_dim_separators): Modify accordingly
+       (rank_specifiers): Update accordingly. Basically do the same
+       thing - instead, collect the brackets here.
+       (opt_rank_sepcifiers): Modify accordingly.
+       (array_type): Modify to actually return the complete type string
+       instead of ignoring the rank_specifiers.
+       (expression_list): Implement to collect the expressions
+       (variable_initializer): Implement. We make it a list of expressions
+       essentially so that we can handle the array_initializer case neatly too.
+       (variable_initializer_list): Implement.
+       (array_initializer): Make it a list of variable_initializers
+       (opt_array_initializer): Modify accordingly.
+
+       * expression.cs (New::NType): Add enumeration to help us
+       keep track of whether we have an object/delegate creation
+       or an array creation.
+       (New:NewType, New::Rank, New::Indices, New::Initializers): New
+       members to hold data about array creation.
+       (New:New): Modify to update NewType
+       (New:New): New Overloaded contructor for the array creation
+       case.
+
+       * cs-parser.jay (array_creation_expression): Implement to call
+       the overloaded New constructor.
+
+2001-08-26  Ravi Pratap  <ravi@che.iitm.ac.in>
+
+       * class.cs (TypeContainer::Constructors): Return member
+       constructors instead of returning null.
+
+2001-08-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * typemanager.cs (InitCoreTypes): Initialize the various core
+       types after we have populated the type manager with the user
+       defined types (this distinction will be important later while
+       compiling corlib.dll)
+
+       * expression.cs, literal.cs, assign.cs, constant.cs: Started work
+       on Expression Classification.  Now all expressions have a method
+       `Resolve' and a method `Emit'.
+
+       * codegen.cs, cs-parser.jay: Fixed the bug that stopped code
+       generation from working.     Also add some temporary debugging
+       code. 
+
+2001-08-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs: Lots of code generation pieces.  This is only the
+       beginning, will continue tomorrow with more touches of polish.  We
+       handle the fundamentals of if, while, do, for, return.  Others are
+       trickier and I need to start working on invocations soon.
+
+       * gen-treedump.cs: Bug fix, use s.Increment here instead of
+       s.InitStatement. 
+
+       * codegen.cs (EmitContext): New struct, used during code
+       emission to keep a context.   Most of the code generation will be
+       here. 
+
+       * cs-parser.jay: Add embedded blocks to the list of statements of
+       this block.  So code generation proceeds in a top down fashion.
+
+2001-08-23  Miguel de Icaza  <miguel@ximian.com>
+
+       * statement.cs: Add support for multiple child blocks.
+
+2001-08-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * codegen.cs (EmitCode): New function, will emit the code for a
+       Block of code given a TypeContainer and its ILGenerator. 
+
+       * statement.cs (Block): Standard public readonly optimization.
+       (Block::Block constructors): Link children. 
+       (Block::Child): Child Linker.
+       (Block::EmitVariables): Emits IL variable declarations.
+
+       * class.cs: Drop support for MethodGroups here, delay until
+       Semantic Analysis.
+       (Method::): Applied the same simplification that I did before, and
+       move from Properties to public readonly fields.
+       (Method::ParameterTypes): Returns the parameter types for the
+       function, and implements a cache that will be useful later when I
+       do error checking and the semantic analysis on the methods is
+       performed.
+       (Constructor::GetCallingConvention): Renamed from CallingConvetion
+       and made a method, optional argument tells whether this is a class
+       or a structure to apply the `has-this' bit.
+       (Method::GetCallingConvention): Implement, returns the calling
+       convention. 
+       (Method::Define): Defines the type, a second pass is performed
+       later to populate the methods.
+
+       (Constructor::ParameterTypes): implement a cache similar to the
+       one on Method::ParameterTypes, useful later when we do semantic
+       analysis. 
+
+       (TypeContainer::EmitMethod):  New method.  Emits methods.
+
+       * expression.cs: Removed MethodGroup class from here.
+
+       * parameter.cs (Parameters::GetCallingConvention): new method.
+
+2001-08-21  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer::Populate): Drop RootContext from the
+       argument. 
+
+       (Constructor::CallingConvention): Returns the calling convention.
+       (Constructor::ParameterTypes): Returns the constructor parameter
+       types. 
+
+       (TypeContainer::AddConstructor): Keep track of default constructor
+       and the default static constructor.
+
+       (Constructor::) Another class that starts using `public readonly'
+       instead of properties. 
+
+       (Constructor::IsDefault): Whether this is a default constructor. 
+
+       (Field::) use readonly public fields instead of properties also.
+
+       (TypeContainer::TypeAttr, TypeContainer::AddConstructor): Keep
+       track of static constructors;  If none is used, turn on
+       BeforeFieldInit in the TypeAttributes. 
+
+       * cs-parser.jay (opt_argument_list): now the return can be null
+       for the cases where there are no arguments. 
+
+       (constructor_declarator): If there is no implicit `base' or
+       `this', then invoke the default parent constructor. 
+
+       * modifiers.cs (MethodAttr): New static function maps a set of
+       modifiers flags into a MethodAttributes enum
+       (FieldAttr): renamed from `Map'.  So now we have FieldAttr,
+       MethodAttr, TypeAttr to represent the various mappings where the
+       modifiers are used.
+       (FieldAttr): Map also `readonly' to `FieldAttributes.InitOnly'  
+
+2001-08-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * parameter.cs (GetParameterInfo): Fix bug where there would be no
+       method arguments.
+
+       * interface.cs (PopulateIndexer): Implemented the code generator
+       for interface indexers.
+
+2001-08-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * interface.cs (InterfaceMemberBase): Now we track the new status
+       here.  
+
+       (PopulateProperty): Implement property population.  Woohoo!  Got
+       Methods and Properties going today. 
+
+       Removed all the properties for interfaces, and replaced them with
+       `public readonly' fields. 
+
+2001-08-16  Miguel de Icaza  <miguel@ximian.com>
+
+       * interface.cs (AddEvent, AddMethod, AddIndexer, AddProperty):
+       initialize their hashtables/arraylists only when they are needed
+       instead of doing this always.
+
+       * parameter.cs: Handle refs and out parameters.
+
+       * cs-parser.jay: Use an ArrayList to construct the arguments
+       instead of the ParameterCollection, and then cast that to a
+       Parameter[] array.
+
+       * parameter.cs: Drop the use of ParameterCollection and use
+       instead arrays of Parameters.
+
+       (GetParameterInfo): Use the Type, not the Name when resolving
+       types. 
+
+2001-08-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * parameter.cs: Eliminate the properties Name, Type and ModFlags,
+       and instead use public readonly fields.
+
+       * class.cs: Put back walking code for type containers.
+
+2001-08-11  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (MakeConstant): Code to define constants.
+
+       * rootcontext.cs (LookupType): New function.  Used to locate types 
+
+
+2001-08-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs: OH MY!  My trick works!   It is amazing how nice
+       this System.Reflection code is.  Kudos to Microsoft
+
+       * typemanager.cs: Implement a type cache and avoid loading all
+       types at boot time.  Wrap in LookupType the internals.  This made
+       the compiler so much faster.  Wow.  I rule!
+
+       * driver.cs: Make sure we always load mscorlib first (for
+       debugging purposes, nothing really important).
+
+       * Renamespaced things that were on `CSC' to `CIR'.  Maybe I should
+       have moved to `CSC' rather than `CIR'.  Oh man!  The confussion!  
+
+       * rootcontext.cs: Lookup types on their namespace;  Lookup types
+       on namespaces that have been imported using the `using' keyword.
+
+       * class.cs (TypeContainer::TypeAttr): Virtualize.
+       (Class::TypeAttr): Return attributes suitable for this bad boy.
+       (Struct::TypeAttr): ditto.
+       Handle nested classes.
+       (TypeContainer::) Remove all the type visiting code, it is now
+       replaced with the rootcontext.cs code
+
+       * rootcontext.cs (GetClassBases): Added support for structs. 
+
+2001-08-06  Miguel de Icaza  <miguel@ximian.com>
+
+       * interface.cs, statement.cs, class.cs, parameter.cs,
+       rootcontext.cs, gen-treedump.cs, enum.cs, cs-parse.jay:
+       Drop use of TypeRefs, and use strings instead.
+
+2001-08-04  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs: 
+
+       * class.cs (Struct::Struct): set the SEALED flags after
+       checking the modifiers.
+       (TypeContainer::TypeAttr): new property, returns the
+       TypeAttributes for a class.  
+
+       * cs-parser.jay (type_list): Oops, list production was creating a
+       new list of base types.
+
+       * rootcontext.cs (StdLib): New property.
+       (GetInterfaceTypeByName): returns an interface by type name, and
+       encapsulates error handling here.
+       (GetInterfaces): simplified.
+       (ResolveTree): Encapsulated all the tree resolution here.
+       (CreateClass, GetClassBases, GetInterfaceOrClass): Create class
+       types. 
+
+       * driver.cs: Add support for --nostdlib, to avoid loading the
+       default assemblies.
+       (Main): Do not put tree resolution here. 
+
+       * rootcontext.cs: Beginning of the class resolution.
+
+2001-08-03  Miguel de Icaza  <miguel@ximian.com>
+
+       * rootcontext.cs: Provide better error reporting. 
+
+       * cs-parser.jay (interface_base): set our $$ to be interfaces.
+
+       * rootcontext.cs (CreateInterface): Handle the case where there
+       are no parent interfaces.
+
+       (CloseTypes): Routine to flush types at the end.
+       (CreateInterface): Track types.
+       (GetInterfaces): Returns an array of Types from the list of
+       defined interfaces.
+
+       * typemanager.c (AddUserType): Mechanism to track user types (puts
+       the type on the global type hash, and allows us to close it at the
+       end). 
+
+2001-08-02  Miguel de Icaza  <miguel@ximian.com>
+
+       * tree.cs: Removed RecordType, added RecordClass, RecordStruct and
+       RecordInterface instead.
+
+       * cs-parser.jay: Updated to reflect changes above.
+
+       * decl.cs (Definition): Keep track of the TypeBuilder type that
+       represents this type here.  Not sure we will use it in the long
+       run, but wont hurt for now.
+
+       * driver.cs: Smaller changes to accomodate the new code.
+
+       Call ResolveInterfaceBases, Call ResolveClassBases, Save assembly
+       when done. 
+
+       * rootcontext.cs (CreateInterface):  New method, used to create
+       the System.TypeBuilder type for interfaces.
+       (ResolveInterfaces): new entry point to resolve the interface
+       hierarchy. 
+       (CodeGen): Property, used to keep track of the code generator.
+
+2001-07-26  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Add a second production for delegate_declaration
+       with `VOID'.
+
+       (enum_body): Put an opt_comma here instead of putting it on
+       enum_body or enum_member_declarations so we can handle trailing
+       commas on enumeration members.  Gets rid of a shift/reduce.
+
+       (type_list): Need a COMMA in the middle.
+
+       (indexer_declaration): Tell tokenizer to recognize get/set
+
+       * Remove old targets.
+
+       * Re-add the parser target.
+
+2001-07-13  Simon Cozens <simon@simon-cozens.org>
+
+       * cs-parser.jay: Add precendence rules for a number of operators
+       ot reduce the number of shift/reduce conflicts in the grammar.
+
+2001-07-17  Miguel de Icaza  <miguel@ximian.com>
+
+       * tree.cs: moved IGenerator interface and renamed it to ITreeDump
+       and put it here.
+
+       Get rid of old crufty code.
+
+       * rootcontext.cs: Use this to keep track of the parsed
+       representation and the defined types available to the program. 
+
+       * gen-treedump.cs: adjust for new convention.
+
+       * type.cs: Split out the type manager, and the assembly builder
+       from here. 
+
+       * typemanager.cs: the type manager will live here now.
+
+       * cil-codegen.cs: And the code generator here. 
+
+2001-07-14  Sean MacIsaac  <macisaac@ximian.com>
+
+       * makefile: Fixed up for easy making.
+
+2001-07-13  Simon Cozens <simon@simon-cozens.org>
+
+       * cs-parser.jay (rank_specifier): Remove a conflict by reordering
+       the 
+
+       (unary_expression): Expand pre_increment_expression and
+       post_decrement_expression to reduce a shift/reduce.
+
+2001-07-11  Simon Cozens
+
+       * cs-tokenizer.cs: Hex numbers should begin with a 0.
+
+       Improve allow_keyword_as_indent name.
+
+2001-06-19  Miguel de Icaza  <miguel@ximian.com>
+
+       * Adjustments for Beta2. 
+
+2001-06-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * decl.cs: Added `Define' abstract method.
+       (InTransit): new property, used to catch recursive definitions. 
+
+       * interface.cs: Implement `Define'. 
+
+       * modifiers.cs: Map Modifiers.constants to
+       System.Reflection.TypeAttribute flags.
+
+       * class.cs: Keep track of types and user-defined types.
+       (BuilderInit): New method for creating an assembly
+       (ResolveType): New function to launch the resolution process, only
+       used by interfaces for now.
+
+       * cs-parser.jay: Keep track of Classes, Structs and Interfaces
+       that are inserted into the name space. 
+
+2001-06-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * ARGH.  I have screwed up my tree so many times due to the use of
+       rsync rather than using CVS.  Going to fix this at once. 
+
+       * driver.cs: Objetify driver.  Load assemblies, use assemblies to
+       load types.
+
+2001-06-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * Experiment successful: Use System.Type rather that our own
+       version of Type.  
+
+2001-05-25  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Removed nsAliases from here.
+
+       Use new namespaces, handle `using XXX;' 
+
+       * namespace.cs: Reimplemented namespace handling, use a recursive
+       definition of the class.  Now we can keep track of using clauses
+       and catch invalid using clauses.
+
+2001-05-24  Miguel de Icaza  <miguel@ximian.com>
+
+       * gen-treedump.cs: Adapted for all the renaming.
+
+       * expression.cs (Expression): this class now has a Type property
+       which returns an expression Type.
+
+       (Probe::, New::, TypeOf::, SizeOf::, Constant::): renamed from
+       `Type', as this has a different meaning now in the base
+
+2001-05-22  Miguel de Icaza  <miguel@ximian.com>
+
+       * interface.cs, class.cs: Removed from all the sources the
+       references to signature computation, as we can not do method
+       signature computation during the parsing time, as we are not
+       trying to solve at that point distinguishing:
+
+       class X {
+               void a (Blah x) {}
+               void a (NS.Blah x) {}
+       }
+
+       Which depending on the context might be valid or not, as we do not
+       know if Blah is the same thing as NS.Blah at that point.
+
+       * Redid everything so the code uses TypeRefs now instead of
+       Types.  TypeRefs are just temporary type placeholders, that need
+       to be resolved.  They initially have a pointer to a string and the
+       current scope in which they are used.  This is used later by the
+       compiler to resolve the reference to an actual Type. 
+
+       * DeclSpace is no longer a CIR.Type, and neither are
+       TypeContainers (Class and Struct) nor Interfaces nor Enums.  They
+       are all DeclSpaces, but no Types. 
+
+       * type.cs (TypeRefManager): This implements the TypeRef manager,
+       which keeps track of all the types that need to be resolved after
+       the parsing has finished. 
+
+2001-05-13  Miguel de Icaza  <miguel@ximian.com>
+
+       * ARGH.  We are going to have to store `foreach' as a class rather
+       than resolving it, as we need to verify error 1579 after name
+       resolution.   *OR* we could keep a flag that says `This request to
+       IEnumerator comes from a foreach statement' which we can then use
+       to generate the error.
+
+2001-05-10  Miguel de Icaza  <miguel@ximian.com>
+
+       * class.cs (TypeContainer.AddMethod): we now add methods to the
+       MethodGroup instead of the method hashtable.  
+
+       * expression.cs: Add MethodGroup abstraction, which gets us one
+       step closer to the specification in the way we handle method
+       declarations.  
+
+       * cs-parser.jay (primary_expression): qualified_identifier now
+       tried to match up an identifier to a local variable reference or
+       to a parameter reference.
+
+       current_local_parameters is now a parser global variable that
+       points to the current parameters for the block, used during name
+       lookup.
+
+       (property_declaration): Now creates an implicit `value' argument to
+       the set accessor.
+
+2001-05-09  Miguel de Icaza  <miguel@ximian.com>
+
+       * parameter.cs: Do not use `param' arguments as part of the
+       signature, per the spec.
+
+2001-05-08  Miguel de Icaza  <miguel@ximian.com>
+
+       * decl.cs: Base class for classes, structs and interfaces.  This
+       is the "Declaration Space" 
+
+       * cs-parser.jay: Use CheckDef for checking declaration errors
+       instead of having one on each function.
+
+       * class.cs: Factor out some code for handling error handling in
+       accordance to the "Declarations" section in the "Basic Concepts"
+       chapter in the ECMA C# spec.
+
+       * interface.cs: Make all interface member classes derive from
+       InterfaceMemberBase.
+
+2001-05-07  Miguel de Icaza  <miguel@ximian.com>
+
+       * Many things: all interfaces are parsed and generated in
+       gen-treedump.  Support for member variables, constructors,
+       destructors, properties, constants is there.
+
+       Beginning of the IL backend, but very little done, just there for
+       testing purposes. 
+
+2001-04-29  Miguel de Icaza  <miguel@ximian.com>
+
+       * cs-parser.jay: Fix labeled statement.
+
+       * cs-tokenizer.cs (escape): Escape " and ' always.
+       ref_line, ref_name: keep track of the line/filename as instructed
+       by #line by the compiler.
+       Parse #line.
+
+2001-04-27  Miguel de Icaza  <miguel@ximian.com>
+
+       * System.CodeDOM/CodeBinaryOperatorExpression.cs: Rearrange enum
+       to match the values in System.CodeDOM.
+
+       Divid renamed to Divide.
+
+       * System.CodeDOM/CodeForLoopStatement.cs: Always have valid
+       statements. 
+       (Statements.set): remove.
+
+       * System.CodeDOM/CodeCatchClause.cs: always have a valid
+       statements. 
+
+       * System.CodeDOM/CodeIfStatement.cs: trueStatements and
+       falseStatements always have valid values. 
+
+       * cs-parser.jay: Use System.CodeDOM now.
+
diff --git a/mcs/bmcs/CryptoConvert.cs b/mcs/bmcs/CryptoConvert.cs
new file mode 100644 (file)
index 0000000..058fe09
--- /dev/null
@@ -0,0 +1,406 @@
+//
+// CryptoConvert.cs - Crypto Convertion Routines
+//
+// Author:
+//     Sebastien Pouliot  <sebastien@ximian.com>
+//
+// (C) 2003 Motus Technologies Inc. (http://www.motus.com)
+// (C) 2004 Novell (http://www.novell.com)
+//
+
+using System;
+using System.Globalization;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace Mono.Security.Cryptography {
+
+#if INSIDE_CORLIB
+       internal
+#else
+       public
+#endif
+       sealed class CryptoConvert {
+
+               private CryptoConvert () 
+               {
+               }
+
+               static private int ToInt32LE (byte [] bytes, int offset)
+               {
+                       return (bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset];
+               }
+
+               static private uint ToUInt32LE (byte [] bytes, int offset)
+               {
+                       return (uint)((bytes [offset+3] << 24) | (bytes [offset+2] << 16) | (bytes [offset+1] << 8) | bytes [offset]);
+               }
+
+               static private byte [] GetBytesLE (int val)
+               {
+                       return new byte [] { 
+                               (byte) (val & 0xff), 
+                               (byte) ((val >> 8) & 0xff), 
+                               (byte) ((val >> 16) & 0xff), 
+                               (byte) ((val >> 24) & 0xff)
+                       };
+                }
+
+               static private byte[] Trim (byte[] array) 
+               {
+                       for (int i=0; i < array.Length; i++) {
+                               if (array [i] != 0x00) {
+                                       byte[] result = new byte [array.Length - i];
+                                       Buffer.BlockCopy (array, i, result, 0, result.Length);
+                                       return result;
+                               }
+                       }
+                       return null;
+               }
+
+               // convert the key from PRIVATEKEYBLOB to RSA
+               // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/Security/private_key_blobs.asp
+               // e.g. SNK files, PVK files
+               static public RSA FromCapiPrivateKeyBlob (byte[] blob) 
+               {
+                       return FromCapiPrivateKeyBlob (blob, 0);
+               }
+
+               static public RSA FromCapiPrivateKeyBlob (byte[] blob, int offset) 
+               {
+                       if (blob == null)
+                               throw new ArgumentNullException ("blob");
+                       if (offset >= blob.Length)
+                               throw new ArgumentException ("blob is too small.");
+
+                       try {
+                               if ((blob [offset]   != 0x07) ||                                // PRIVATEKEYBLOB (0x07)
+                                   (blob [offset+1] != 0x02) ||                                // Version (0x02)
+                                   (blob [offset+2] != 0x00) ||                                // Reserved (word)
+                                   (blob [offset+3] != 0x00) ||
+                                   (ToUInt32LE (blob, offset+8) != 0x32415352))        // DWORD magic = RSA2
+                                       throw new CryptographicException ("Invalid blob header");
+                               
+                               // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
+                               int algId = ToInt32LE (blob, offset+4);
+
+                               // DWORD bitlen
+                               int bitLen = ToInt32LE (blob, offset+12);
+
+                               // DWORD public exponent
+                               RSAParameters rsap = new RSAParameters ();
+                               byte[] exp = new byte [4];
+                               Buffer.BlockCopy (blob, offset+16, exp, 0, 4);
+                               Array.Reverse (exp);
+                               rsap.Exponent = Trim (exp);
+                       
+                               int pos = offset+20;
+                               // BYTE modulus[rsapubkey.bitlen/8];
+                               int byteLen = (bitLen >> 3);
+                               rsap.Modulus = new byte [byteLen];
+                               Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen);
+                               Array.Reverse (rsap.Modulus);
+                               pos += byteLen;
+
+                               // BYTE prime1[rsapubkey.bitlen/16];
+                               int byteHalfLen = (byteLen >> 1);
+                               rsap.P = new byte [byteHalfLen];
+                               Buffer.BlockCopy (blob, pos, rsap.P, 0, byteHalfLen);
+                               Array.Reverse (rsap.P);
+                               pos += byteHalfLen;
+
+                               // BYTE prime2[rsapubkey.bitlen/16];
+                               rsap.Q = new byte [byteHalfLen];
+                               Buffer.BlockCopy (blob, pos, rsap.Q, 0, byteHalfLen);
+                               Array.Reverse (rsap.Q);
+                               pos += byteHalfLen;
+
+                               // BYTE exponent1[rsapubkey.bitlen/16];
+                               rsap.DP = new byte [byteHalfLen];
+                               Buffer.BlockCopy (blob, pos, rsap.DP, 0, byteHalfLen);
+                               Array.Reverse (rsap.DP);
+                               pos += byteHalfLen;
+
+                               // BYTE exponent2[rsapubkey.bitlen/16];
+                               rsap.DQ = new byte [byteHalfLen];
+                               Buffer.BlockCopy (blob, pos, rsap.DQ, 0, byteHalfLen);
+                               Array.Reverse (rsap.DQ);
+                               pos += byteHalfLen;
+
+                               // BYTE coefficient[rsapubkey.bitlen/16];
+                               rsap.InverseQ = new byte [byteHalfLen];
+                               Buffer.BlockCopy (blob, pos, rsap.InverseQ, 0, byteHalfLen);
+                               Array.Reverse (rsap.InverseQ);
+                               pos += byteHalfLen;
+
+                               // ok, this is hackish but CryptoAPI support it so...
+                               // note: only works because CRT is used by default
+                               // http://bugzilla.ximian.com/show_bug.cgi?id=57941
+                               rsap.D = new byte [byteLen]; // must be allocated
+                               if (pos + byteLen + offset <= blob.Length) {
+                                       // BYTE privateExponent[rsapubkey.bitlen/8];
+                                       Buffer.BlockCopy (blob, pos, rsap.D, 0, byteLen);
+                                       Array.Reverse (rsap.D);
+                               }
+
+                               RSA rsa = (RSA)RSA.Create ();
+                               rsa.ImportParameters (rsap);
+                               return rsa;
+                       }
+                       catch (Exception e) {
+                               throw new CryptographicException ("Invalid blob.", e);
+                       }
+               }
+
+               static public byte[] ToCapiPrivateKeyBlob (RSA rsa) 
+               {
+                       RSAParameters p = rsa.ExportParameters (true);
+                       int keyLength = p.Modulus.Length; // in bytes
+                       byte[] blob = new byte [20 + (keyLength << 2) + (keyLength >> 1)];
+
+                       blob [0] = 0x07;        // Type - PRIVATEKEYBLOB (0x07)
+                       blob [1] = 0x02;        // Version - Always CUR_BLOB_VERSION (0x02)
+                       // [2], [3]             // RESERVED - Always 0
+                       blob [5] = 0x24;        // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN)
+                       blob [8] = 0x52;        // Magic - RSA2 (ASCII in hex)
+                       blob [9] = 0x53;
+                       blob [10] = 0x41;
+                       blob [11] = 0x32;
+
+                       byte[] bitlen = GetBytesLE (keyLength << 3);
+                       blob [12] = bitlen [0]; // bitlen
+                       blob [13] = bitlen [1]; 
+                       blob [14] = bitlen [2]; 
+                       blob [15] = bitlen [3];
+
+                       // public exponent (DWORD)
+                       int pos = 16;
+                       int n = p.Exponent.Length;
+                       while (n > 0)
+                               blob [pos++] = p.Exponent [--n];
+                       // modulus
+                       pos = 20;
+                       byte[] part = p.Modulus;
+                       int len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Buffer.BlockCopy (part, 0, blob, pos, len);
+                       pos += len;
+                       // private key
+                       part = p.P;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Buffer.BlockCopy (part, 0, blob, pos, len);
+                       pos += len;
+
+                       part = p.Q;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Buffer.BlockCopy (part, 0, blob, pos, len);
+                       pos += len;
+
+                       part = p.DP;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Buffer.BlockCopy (part, 0, blob, pos, len);
+                       pos += len;
+
+                       part = p.DQ;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Buffer.BlockCopy (part, 0, blob, pos, len);
+                       pos += len;
+
+                       part = p.InverseQ;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Buffer.BlockCopy (part, 0, blob, pos, len);
+                       pos += len;
+
+                       part = p.D;
+                       len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Buffer.BlockCopy (part, 0, blob, pos, len);
+
+                       return blob;
+               }
+
+               static public RSA FromCapiPublicKeyBlob (byte[] blob) 
+               {
+                       return FromCapiPublicKeyBlob (blob, 0);
+               }
+
+               static public RSA FromCapiPublicKeyBlob (byte[] blob, int offset) 
+               {
+                       if (blob == null)
+                               throw new ArgumentNullException ("blob");
+                       if (offset >= blob.Length)
+                               throw new ArgumentException ("blob is too small.");
+
+                       try {
+                               if ((blob [offset]   != 0x06) ||                                // PUBLICKEYBLOB (0x06)
+                                   (blob [offset+1] != 0x02) ||                                // Version (0x02)
+                                   (blob [offset+2] != 0x00) ||                                // Reserved (word)
+                                   (blob [offset+3] != 0x00) || 
+                                   (ToUInt32LE (blob, offset+8) != 0x31415352))        // DWORD magic = RSA1
+                                       throw new CryptographicException ("Invalid blob header");
+
+                               // ALGID (CALG_RSA_SIGN, CALG_RSA_KEYX, ...)
+                               int algId = ToInt32LE (blob, offset+4);
+
+                               // DWORD bitlen
+                               int bitLen = ToInt32LE (blob, offset+12);
+
+                               // DWORD public exponent
+                               RSAParameters rsap = new RSAParameters ();
+                               rsap.Exponent = new byte [3];
+                               rsap.Exponent [0] = blob [offset+18];
+                               rsap.Exponent [1] = blob [offset+17];
+                               rsap.Exponent [2] = blob [offset+16];
+                       
+                               int pos = offset+20;
+                               // BYTE modulus[rsapubkey.bitlen/8];
+                               int byteLen = (bitLen >> 3);
+                               rsap.Modulus = new byte [byteLen];
+                               Buffer.BlockCopy (blob, pos, rsap.Modulus, 0, byteLen);
+                               Array.Reverse (rsap.Modulus);
+
+                               RSA rsa = (RSA)RSA.Create ();
+                               rsa.ImportParameters (rsap);
+                               return rsa;
+                       }
+                       catch (Exception e) {
+                               throw new CryptographicException ("Invalid blob.", e);
+                       }
+               }
+
+               static public byte[] ToCapiPublicKeyBlob (RSA rsa) 
+               {
+                       RSAParameters p = rsa.ExportParameters (false);
+                       int keyLength = p.Modulus.Length; // in bytes
+                       byte[] blob = new byte [20 + keyLength];
+
+                       blob [0] = 0x06;        // Type - PUBLICKEYBLOB (0x06)
+                       blob [1] = 0x02;        // Version - Always CUR_BLOB_VERSION (0x02)
+                       // [2], [3]             // RESERVED - Always 0
+                       blob [5] = 0x24;        // ALGID - Always 00 24 00 00 (for CALG_RSA_SIGN)
+                       blob [8] = 0x52;        // Magic - RSA1 (ASCII in hex)
+                       blob [9] = 0x53;
+                       blob [10] = 0x41;
+                       blob [11] = 0x31;
+
+                       byte[] bitlen = GetBytesLE (keyLength << 3);
+                       blob [12] = bitlen [0]; // bitlen
+                       blob [13] = bitlen [1]; 
+                       blob [14] = bitlen [2]; 
+                       blob [15] = bitlen [3];
+
+                       // public exponent (DWORD)
+                       int pos = 16;
+                       int n = p.Exponent.Length;
+                       while (n > 0)
+                               blob [pos++] = p.Exponent [--n];
+                       // modulus
+                       pos = 20;
+                       byte[] part = p.Modulus;
+                       int len = part.Length;
+                       Array.Reverse (part, 0, len);
+                       Buffer.BlockCopy (part, 0, blob, pos, len);
+                       pos += len;
+                       return blob;
+               }
+
+               // PRIVATEKEYBLOB
+               // PUBLICKEYBLOB
+               static public RSA FromCapiKeyBlob (byte[] blob) 
+               {
+                       return FromCapiKeyBlob (blob, 0);
+               }
+
+               static public RSA FromCapiKeyBlob (byte[] blob, int offset) 
+               {
+                       if (blob == null)
+                               throw new ArgumentNullException ("blob");
+                       if (offset >= blob.Length)
+                               throw new ArgumentException ("blob is too small.");
+
+                       switch (blob [offset]) {
+                               case 0x00:
+                                       // this could be a public key inside an header
+                                       // like "sn -e" would produce
+                                       if (blob [offset + 12] == 0x06) {
+                                               return FromCapiPublicKeyBlob (blob, offset + 12);
+                                       }
+                                       break;
+                               case 0x06:
+                                       return FromCapiPublicKeyBlob (blob, offset);
+                               case 0x07:
+                                       return FromCapiPrivateKeyBlob (blob, offset);
+                       }
+                       throw new CryptographicException ("Unknown blob format.");
+               }
+
+               static public byte[] ToCapiKeyBlob (AsymmetricAlgorithm keypair, bool includePrivateKey) 
+               {
+                       if (keypair == null)
+                               throw new ArgumentNullException ("keypair");
+
+                       // check between RSA and DSA (and potentially others like DH)
+                       if (keypair is RSA)
+                               return ToCapiKeyBlob ((RSA)keypair, includePrivateKey);
+                       else
+                               return null;    // TODO
+               }
+
+               static public byte[] ToCapiKeyBlob (RSA rsa, bool includePrivateKey) 
+               {
+                       if (rsa == null)
+                               throw new ArgumentNullException ("rsa");
+
+                       RSAParameters p = rsa.ExportParameters (includePrivateKey);
+                       if (includePrivateKey)
+                               return ToCapiPrivateKeyBlob (rsa);
+                       else
+                               return ToCapiPublicKeyBlob (rsa);
+               }
+
+               static public string ToHex (byte[] input) 
+               {
+                       if (input == null)
+                               return null;
+
+                       StringBuilder sb = new StringBuilder (input.Length * 2);
+                       foreach (byte b in input) {
+                               sb.Append (b.ToString ("X2", CultureInfo.InvariantCulture));
+                       }
+                       return sb.ToString ();
+               }
+
+               static private byte FromHexChar (char c) 
+               {
+                       if ((c >= 'a') && (c <= 'f'))
+                               return (byte) (c - 'a' + 10);
+                       if ((c >= 'A') && (c <= 'F'))
+                               return (byte) (c - 'A' + 10);
+                       if ((c >= '0') && (c <= '9'))
+                               return (byte) (c - '0');
+                       throw new ArgumentException ("invalid hex char");
+               }
+
+               static public byte[] FromHex (string hex) 
+               {
+                       if (hex == null)
+                               return null;
+                       if ((hex.Length & 0x1) == 0x1)
+                               throw new ArgumentException ("Length must be a multiple of 2");
+
+                       byte[] result = new byte [hex.Length >> 1];
+                       int n = 0;
+                       int i = 0;
+                       while (n < result.Length) {
+                               result [n] = (byte) (FromHexChar (hex [i++]) << 4);
+                               result [n++] += FromHexChar (hex [i++]);
+                       }
+                       return result;
+               }
+       }
+}
diff --git a/mcs/bmcs/Makefile b/mcs/bmcs/Makefile
new file mode 100644 (file)
index 0000000..1ac0492
--- /dev/null
@@ -0,0 +1,41 @@
+#
+# This makefile needs work, currently we overwrite the value of `bmcs.exe',
+# the reason is that we need this to be compiled with gmcs, so it uses the
+# .NET 2.0 profile.
+#
+thisdir := bmcs
+SUBDIRS := 
+include ../build/rules.make
+
+#uncomment to enable some debug stuff
+#DEBUG_FLAGS=/define:MCS_DEBUG
+
+BOOTSTRAP_MCS = MONO_PATH="$(topdir)/class/lib/net_2_0_bootstrap$(PLATFORM_PATH_SEPARATOR)$$MONO_PATH" $(RUNTIME) $(topdir)/class/lib/net_2_0_bootstrap/mcs.exe $(DEBUG_FLAGS)
+
+BUILT_SOURCES = mb-parser.cs
+
+EXTRA_DISTFILES = mb-parser.jay
+
+PROGRAM_COMPILE = $(BOOT_COMPILE)
+
+CLEAN_FILES = y.output
+
+PROGRAM = bmcs.exe
+
+mb-parser.cs: mb-parser.jay $(topdir)/jay/skeleton.cs
+       $(topdir)/jay/jay -ctv < $(topdir)/jay/skeleton.cs $< > jay-tmp.out && mv jay-tmp.out $@
+
+include ../build/executable.make
+
+bmcs.exe: mb-parser.cs
+       gmcs    -d:NET_1_1 -d:ONLY_1_1 -debug /target:exe /out:bmcs.exe mb-parser.cs  @bmcs.exe.sources -nowarn:219 -nowarn:162
+
+install-as-mbas: all
+       cp ../class/lib/default/bmcs.exe $(prefix)/lib/mono/1.0/mbas.exe
+
+winstall: all
+       cp ../class/lib/default/bmcs.exe  /cygdrive/c/WINDOWS/Microsoft.NET/Framework/v1.1.4322/
+
+winstall-as-mbas: all
+       cp ../class/lib/default/bmcs.exe  /cygdrive/c/WINDOWS/Microsoft.NET/Framework/v1.1.4322/
+       cp ../class/lib/default/bmcs.exe  /cygdrive/c/WINDOWS/Microsoft.NET/Framework/v1.1.4322/mbas.exe
diff --git a/mcs/bmcs/README b/mcs/bmcs/README
new file mode 100644 (file)
index 0000000..0b2ee6a
--- /dev/null
@@ -0,0 +1,22 @@
+* This is BMCS
+
+       Last merge to GMCS: 38733
+
+       BMCS is a new fork of the generics compiler from revision
+       38733 (11th of January 2005).  
+
+       This new compiler is based on the changes that Jambunathan did
+       to mcs from November 30th, 2004 to integrate the existing mbas
+       compiler with a more recent mcs.
+
+       We have ported those changes to use `gmcs' so that we get
+       support for generics into our VB compiler eventually.
+
+       Work toward integrating the improvements from mbas will go here.
+
+* LICENSING
+
+       Notice that the compiler might eventually need to go into the
+       class libraries.  We request that contributors grant us permission      
+       to relicense the code under the MIT X11 license if we have to.
+
diff --git a/mcs/bmcs/anonymous.cs b/mcs/bmcs/anonymous.cs
new file mode 100644 (file)
index 0000000..d0fa55e
--- /dev/null
@@ -0,0 +1,1144 @@
+//
+// anonymous.cs: Support for anonymous methods
+//
+// Author:
+//   Miguel de Icaza (miguel@ximain.com)
+//
+// (C) 2003, 2004 Novell, Inc.
+//
+// TODO: Ideally, we should have the helper classes emited as a hierarchy to map
+// their nesting, and have the visibility set to private, instead of NestedAssembly
+//
+//
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace Mono.CSharp {
+
+       public class AnonymousMethod : Expression {
+               // Used to generate unique method names.
+               static int anonymous_method_count;
+                   
+               // An array list of AnonymousMethodParameter or null
+               public Parameters Parameters;
+               
+               //
+               // The block that makes up the body for the anonymous mehtod
+               //
+               public ToplevelBlock Block;
+
+               //
+               // The container block for this anonymous method.
+               //
+               public Block ContainingBlock;
+
+               //
+               // The implicit method we create
+               //
+               public Method method;
+
+               MethodInfo invoke_mb;
+               
+               // The emit context for the anonymous method
+               public EmitContext aec;
+               public InternalParameters amp;
+               bool unreachable;
+               
+               //
+               // The modifiers applied to the method, we aggregate them
+               //
+               int method_modifiers = Modifiers.INTERNAL;
+               
+               //
+               // During the resolve stage of the anonymous method body,
+               // we discover the actual scope where we are hosted, or
+               // null to host the method in the same class
+               //
+               public ScopeInfo Scope;
+
+               //
+               // Points to our container anonymous method if its present
+               //
+               public AnonymousMethod ContainerAnonymousMethod;
+               
+               public AnonymousMethod (Parameters parameters, ToplevelBlock container, ToplevelBlock block, Location l)
+               {
+                       Parameters = parameters;
+                       Block = block;
+                       loc = l;
+
+                       //
+                       // The order is important: this setups the CaptureContext tree hierarchy.
+                       //
+                       container.SetHaveAnonymousMethods (l, this);
+                       block.SetHaveAnonymousMethods (l, this);
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       //
+                       // Set class type, set type
+                       //
+
+                       eclass = ExprClass.Value;
+
+                       //
+                       // This hack means `The type is not accessible
+                       // anywhere', we depend on special conversion
+                       // rules.
+                       // 
+                       type = TypeManager.anonymous_method_type;
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       // nothing, as we only exist to not do anything.
+               }
+
+               //
+               // Creates the host for the anonymous method
+               //
+               bool CreateMethodHost (EmitContext ec, Type return_type)
+               {
+                       //
+                       // Crude hack follows: we replace the TypeBuilder during the
+                       // definition to get the method hosted in the right class
+                       //
+                       
+                       TypeBuilder current_type = ec.TypeContainer.TypeBuilder;
+                       TypeBuilder type_host = Scope == null ? current_type : Scope.ScopeTypeBuilder;
+
+                       if (current_type == null)
+                               throw new Exception ("The current_type is null");
+                       
+                       if (type_host == null)
+                               throw new Exception ("Type host is null");
+                       
+                       if (current_type == type_host && ec.IsStatic){
+                               if (ec.IsStatic)
+                                       method_modifiers |= Modifiers.STATIC;
+                               current_type = null;
+                       } 
+
+                       method = new Method (
+                               (TypeContainer) ec.TypeContainer, null,
+                               new TypeExpression (return_type, loc),
+                               method_modifiers, false, new MemberName ("<#AnonymousMethod>" + anonymous_method_count++),
+                               Parameters, null, loc);
+                       method.Block = Block;
+
+                       
+                       //
+                       // Swap the TypeBuilder while we define the method, then restore
+                       //
+                       if (current_type != null)
+                               ec.TypeContainer.TypeBuilder = type_host;
+                       bool res = method.Define ();
+                       if (current_type != null)
+                               ec.TypeContainer.TypeBuilder = current_type;
+                       return res;
+               }
+               
+               void Error_ParameterMismatch (Type t)
+               {
+                       Report.Error (1661, loc, "Anonymous method could not be converted to delegate `" +
+                                     "{0}' since there is a parameter mismatch", t);
+       }
+
+               //
+               // Returns true if this anonymous method can be implicitly
+               // converted to the delegate type `delegate_type'
+               //
+               public Expression Compatible (EmitContext ec, Type delegate_type, bool probe)
+               {
+                       //
+                       // At this point its the first time we know the return type that is 
+                       // needed for the anonymous method.  We create the method here.
+                       //
+
+                       MethodGroupExpr invoke_mg = Delegate.GetInvokeMethod (ec, delegate_type, loc);
+                       invoke_mb = (MethodInfo) invoke_mg.Methods [0];
+                       ParameterData invoke_pd = Invocation.GetParameterData (invoke_mb);
+
+                       //
+                       // If implicit parameters are set, then we must check for out in the parameters
+                       // and flag it accordingly.
+                       //
+                       bool out_invalid_check = false;
+                       
+                       if (Parameters == null){
+                               int i, j;
+                               out_invalid_check = true;
+                               
+                               //
+                               // We provide a set of inaccessible parameters
+                               //
+                               int params_idx = -1;
+                               for (i = 0; i < invoke_pd.Count; i++){
+                                       if (invoke_pd.ParameterModifier (i) == Parameter.Modifier.PARAMS)
+                                               params_idx = i;
+                               }
+                               int n = invoke_pd.Count - (params_idx != -1 ? 1 : 0);
+                               Parameter [] fixedpars = new Parameter [n];
+                               
+                               for (i =  j = 0; i < invoke_pd.Count; i++){
+                                       if (invoke_pd.ParameterModifier (i) == Parameter.Modifier.PARAMS)
+                                               continue;
+                                       fixedpars [j] = new Parameter (
+                                               new TypeExpression (invoke_pd.ParameterType (i), loc),
+                                               "+" + j, invoke_pd.ParameterModifier (i), null);
+                                       j++;
+                               }
+                               
+                               Parameter variable = null;
+                               if (params_idx != -1){
+                                       variable = new Parameter (
+                                               new TypeExpression (invoke_pd.ParameterType (params_idx), loc),
+                                               "+" + params_idx, invoke_pd.ParameterModifier (params_idx), null);
+                               }
+
+                               Parameters = new Parameters (fixedpars, variable, loc);
+                       }
+                       
+                       //
+                       // First, parameter types of `delegate_type' must be compatible
+                       // with the anonymous method.
+                       //
+                       amp = new InternalParameters (Parameters.GetParameterInfo (ec), Parameters);
+                       
+                       if (amp.Count != invoke_pd.Count){
+                               if (!probe){
+                                       Report.Error (1593, loc, 
+                                             "Anonymous method has {0} parameters, while delegate requires {1}",
+                                             amp.Count, invoke_pd.Count);
+                                       Error_ParameterMismatch (delegate_type);
+                               }
+                               return null;
+                       }
+                       
+                       for (int i = 0; i < amp.Count; i++){
+                               Parameter.Modifier amp_mod = amp.ParameterModifier (i);
+                               if (amp_mod != invoke_pd.ParameterModifier (i)){
+                                       if (!probe){
+                                               Report.Error (1676, loc, 
+                                                     "Signature mismatch in parameter modifier for parameter #0", i + 1);
+                                               Error_ParameterMismatch (delegate_type);
+                                       }
+                                       return null;
+                               }
+                               
+                               if (amp.ParameterType (i) != invoke_pd.ParameterType (i)){
+                                       if (!probe){
+                                               Report.Error (1678, loc, 
+                                                                     "Signature mismatch in parameter {0}: need `{1}' got `{2}'", i + 1,
+                                                                     TypeManager.CSharpName (invoke_pd.ParameterType (i)),
+                                                                     TypeManager.CSharpName (amp.ParameterType (i)));
+                                               Error_ParameterMismatch (delegate_type);
+                                       }
+                                       return null;
+                               }
+                               
+                               if (out_invalid_check && (invoke_pd.ParameterModifier (i) & Parameter.Modifier.OUT) != 0){
+                                       if (!probe){
+                                               Report.Error (1676, loc,"Parameter {0} must include the `out' modifier ", i+1);
+                                               Error_ParameterMismatch (delegate_type);
+                                       }
+                                       return null;
+                               }
+                       }
+
+                       //
+                       // If we are only probing, return ourselves
+                       //
+                       if (probe)
+                               return this;
+                       
+                       //
+                       // Second: the return type of the delegate must be compatible with 
+                       // the anonymous type.   Instead of doing a pass to examine the block
+                       // we satisfy the rule by setting the return type on the EmitContext
+                       // to be the delegate type return type.
+                       //
+
+                       //MethodBuilder builder = method_data.MethodBuilder;
+                       //ILGenerator ig = builder.GetILGenerator ();
+
+                       
+                       aec = new EmitContext (
+                               ec.TypeContainer, ec.DeclSpace, loc, null,
+                               invoke_mb.ReturnType,
+                               /* REVIEW */ (ec.InIterator ? Modifiers.METHOD_YIELDS : 0) |
+                               (ec.InUnsafe ? Modifiers.UNSAFE : 0),
+                               /* No constructor */ false);
+
+                       aec.CurrentAnonymousMethod = this;
+                       ContainerAnonymousMethod = ec.CurrentAnonymousMethod;
+                       ContainingBlock = ec.CurrentBlock;
+               
+                       if (aec.ResolveTopBlock (ec, Block, amp, loc, out unreachable))
+                               return new AnonymousDelegate (this, delegate_type, loc).Resolve (ec);
+
+                       return null;
+               }
+
+               public MethodBuilder GetMethodBuilder ()
+               {
+                       return method.MethodData.MethodBuilder;
+               }
+               
+               public void EmitMethod (EmitContext ec)
+               {
+                       if (!CreateMethodHost (ec, invoke_mb.ReturnType))
+                               return;
+
+                       MethodBuilder builder = GetMethodBuilder ();
+                       ILGenerator ig = builder.GetILGenerator ();
+                       aec.ig = ig;
+                       
+                       Parameters.LabelParameters (aec, builder, loc);
+
+                       //
+                       // Adjust based on the computed state of the
+                       // method from CreateMethodHost
+                       
+                       if ((method_modifiers & Modifiers.STATIC) != 0)
+                               aec.IsStatic = true;
+                       
+                       aec.EmitMeta (Block, amp);
+                       aec.EmitResolvedTopBlock (Block, unreachable);
+               }
+
+               public static void Error_AddressOfCapturedVar (string name, Location loc)
+               {
+                       Report.Error (1686, loc,
+                                     "Variable {0} is captured in an anonymous method and its address is also being taken: they are exclusive", name);
+               }
+       }
+
+       //
+       // This will emit the code for the delegate, as well delegate creation on the host
+       //
+       public class AnonymousDelegate : DelegateCreation {
+               AnonymousMethod am;
+
+               public AnonymousDelegate (AnonymousMethod am, Type target_type, Location l)
+               {
+                       type = target_type;
+                       loc = l;
+                       this.am = am;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       eclass = ExprClass.Value;
+                       return this;
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       am.EmitMethod (ec);
+
+                       //
+                       // Now emit the delegate creation.
+                       //
+                       if ((am.method.ModFlags & Modifiers.STATIC) == 0)
+                               delegate_instance_expression = new AnonymousInstance (am);
+                       
+                       Expression ml = Expression.MemberLookup (ec, type, ".ctor", loc);
+                       constructor_method = ((MethodGroupExpr) ml).Methods [0];
+                       delegate_method = am.GetMethodBuilder ();
+                       base.Emit (ec);
+               }
+
+               class AnonymousInstance : Expression {
+                       AnonymousMethod am;
+                       
+                       public AnonymousInstance (AnonymousMethod am)
+                       {
+                               this.am = am;
+                               eclass = ExprClass.Value;
+                       }
+
+                       public override Expression DoResolve (EmitContext ec)
+                       {
+                               return this;
+                       }
+                       
+                       public override void Emit (EmitContext ec)
+                       {
+                               am.aec.EmitMethodHostInstance (ec, am);
+                       }
+               }
+       }
+
+       class CapturedParameter {
+               public Type Type;
+               public FieldBuilder FieldBuilder;
+               public int Idx;
+
+               public CapturedParameter (Type type, int idx)
+               {
+                       Type = type;
+                       Idx = idx;
+               }
+       }
+
+       //
+       // Here we cluster all the variables captured on a given scope, we also
+       // keep some extra information that might be required on each scope.
+       //
+       public class ScopeInfo {
+               public CaptureContext CaptureContext;
+               public ScopeInfo ParentScope;
+               public Block ScopeBlock;
+               public bool NeedThis = false;
+               public bool HostsParameters = false;
+               
+               // For tracking the number of scopes created.
+               public int id;
+               static int count;
+               bool inited = false;
+               
+               ArrayList locals = new ArrayList ();
+               ArrayList children = new ArrayList ();
+
+               //
+               // The types and fields generated
+               //
+               public TypeBuilder ScopeTypeBuilder;
+               public ConstructorBuilder ScopeConstructor;
+               public FieldBuilder THIS;
+               public FieldBuilder ParentLink;
+
+               //
+               // Points to the object of type `ScopeTypeBuilder' that
+               // holds the data for the scope
+               //
+               public LocalBuilder ScopeInstance;
+
+               
+               public ScopeInfo (CaptureContext cc, Block b)
+               {
+                       CaptureContext = cc;
+                       ScopeBlock = b;
+                       id = count++;
+
+                       cc.AddScope (this);
+               }
+
+               public void AddLocal (LocalInfo li)
+               {
+                       if (locals.Contains (li))
+                               return;
+
+                       locals.Add (li);
+}
+       
+               public bool IsCaptured (LocalInfo li)
+               {
+                       return locals.Contains (li);
+               }
+               
+               public void AddChild (ScopeInfo si)
+               {
+                       if (children.Contains (si))
+                               return;
+                       children.Add (si);
+               }
+
+               static int indent = 0;
+
+               void Pad ()
+               {
+                       for (int i = 0; i < indent; i++)
+                               Console.Write ("    ");
+               }
+
+               void EmitDebug ()
+               {
+                       //Console.WriteLine (Environment.StackTrace);
+                       Pad ();
+                       Console.WriteLine ("START");
+                       indent++;
+                       Pad ();
+                       Console.WriteLine ("NeedThis=" + NeedThis);
+                       foreach (LocalInfo li in locals){
+                               Pad ();
+                               Console.WriteLine ("var {0}", li.Name);
+                       }
+                       
+                       foreach (ScopeInfo si in children)
+                               si.EmitDebug ();
+                       indent--;
+                       Pad ();
+                       Console.WriteLine ("END");
+               }
+               
+               public string MakeHelperName ()
+               {
+                       return String.Format ("<>AnonHelp<{0}>", id);
+               }
+
+               public void EmitScopeConstructor ()
+               {
+                       Type [] constructor_types = TypeManager.NoTypes;
+                       Parameters constructor_parameters = Parameters.EmptyReadOnlyParameters;
+                       ScopeConstructor = ScopeTypeBuilder.DefineConstructor (
+                               MethodAttributes.Public | MethodAttributes.HideBySig |
+                               MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
+                               CallingConventions.HasThis, constructor_types);
+                       InternalParameters parameter_info = new InternalParameters (constructor_types, constructor_parameters);
+                       TypeManager.RegisterMethod (ScopeConstructor, parameter_info, constructor_types);
+
+                       ILGenerator cig = ScopeConstructor.GetILGenerator ();
+                       cig.Emit (OpCodes.Ldarg_0);
+                       cig.Emit (OpCodes.Call, TypeManager.object_ctor);
+                       cig.Emit (OpCodes.Ret);
+               }
+               
+               public void EmitScopeType (EmitContext ec)
+               {
+                       //EmitDebug ();
+
+                       if (ScopeTypeBuilder != null)
+                               return;
+                       
+                       ILGenerator ig = ec.ig;
+                       TypeBuilder container = ec.TypeContainer.TypeBuilder;
+
+                       ScopeTypeBuilder = container.DefineNestedType (
+                               MakeHelperName (), TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.NestedAssembly,
+                               TypeManager.object_type, null);
+
+                       if (NeedThis)
+                               THIS = ScopeTypeBuilder.DefineField ("<>THIS", container, FieldAttributes.Assembly);
+
+                       if (ParentScope != null){
+                               if (ParentScope.ScopeTypeBuilder == null){
+                                       throw new Exception (String.Format ("My parent has not been initialized {0} and {1}", ParentScope, this));
+                               }
+                               
+                               ParentLink = ScopeTypeBuilder.DefineField ("<>parent", ParentScope.ScopeTypeBuilder,
+                                                                          FieldAttributes.Assembly);
+                       }
+                       
+                       if (NeedThis && ParentScope != null)
+                               throw new Exception ("I was not expecting THIS && having a parent");
+
+                       foreach (LocalInfo info in locals){
+                               info.FieldBuilder = ScopeTypeBuilder.DefineField (
+                                       info.Name, info.VariableType, FieldAttributes.Assembly);
+                       }
+
+                       if (HostsParameters){
+                               Hashtable captured_parameters = CaptureContext.captured_parameters;
+                               
+                               foreach (DictionaryEntry de in captured_parameters){
+                                       string name = (string) de.Key;
+                                       CapturedParameter cp = (CapturedParameter) de.Value;
+                                       FieldBuilder fb;
+                                       
+                                       fb = ScopeTypeBuilder.DefineField ("<p:" + name + ">", cp.Type, FieldAttributes.Assembly);
+                                       cp.FieldBuilder = fb;
+                               }
+                       }
+
+                       EmitScopeConstructor ();
+                       foreach (ScopeInfo si in children){
+                               si.EmitScopeType (ec);
+                       }
+               }
+
+               public void CloseTypes ()
+               {
+                       RootContext.RegisterHelperClass (ScopeTypeBuilder);
+                       foreach (ScopeInfo si in children)
+                               si.CloseTypes ();
+               }
+
+               //
+               // Emits the initialization code for the scope
+               //
+               public void EmitInitScope (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       if (inited)
+                               return;
+
+                       ig.Emit (OpCodes.Newobj, (ConstructorInfo) ScopeConstructor);
+                       ScopeInstance = ig.DeclareLocal (ScopeTypeBuilder);
+                       ig.Emit (OpCodes.Stloc, ScopeInstance);
+
+                       if (THIS != null){
+                               ig.Emit (OpCodes.Ldloc, ScopeInstance);
+                               ig.Emit (OpCodes.Ldarg_0);
+                               ig.Emit (OpCodes.Stfld, THIS);
+                       }
+
+                       //
+                       // Copy the parameter values, if any
+                       //
+                       int extra = ec.IsStatic ? 0 : 1;
+                       if (HostsParameters){
+                               Hashtable captured_parameters = CaptureContext.captured_parameters;
+                               
+                               foreach (DictionaryEntry de in captured_parameters){
+                                       string name = (string) de.Key;
+                                       CapturedParameter cp = (CapturedParameter) de.Value;
+
+                                       ig.Emit (OpCodes.Ldloc, ScopeInstance);
+                                       ParameterReference.EmitLdArg (ig, cp.Idx + extra);
+                                       ig.Emit (OpCodes.Stfld, cp.FieldBuilder);
+                               }
+                       }
+                       
+                       if (ParentScope != null){
+                               //
+                               // Only emit initialization in our capturecontext world
+                               //
+                               if (ParentScope.CaptureContext == CaptureContext){
+                                       ig.Emit (OpCodes.Ldloc, ScopeInstance);
+                                       ig.Emit (OpCodes.Ldloc, ParentScope.ScopeInstance);
+                                       ig.Emit (OpCodes.Stfld, ParentLink);
+                               } else {
+                                       ig.Emit (OpCodes.Ldloc, ScopeInstance);
+                                       ig.Emit (OpCodes.Ldarg_0);
+                                       ig.Emit (OpCodes.Stfld, ParentLink);
+                               }
+                       }
+                       inited = true;
+               }
+
+               static void DoPath (StringBuilder sb, ScopeInfo start)
+               {
+                       if (start.ParentScope != null){
+                               DoPath (sb, start.ParentScope);
+                               sb.Append (", ");
+                       }
+                       sb.Append ((start.id).ToString ());
+               }
+               
+               public override string ToString ()
+               {
+                       StringBuilder sb = new StringBuilder ();
+                       
+                       sb.Append ("{");
+                       if (CaptureContext != null){
+                               sb.Append (CaptureContext.ToString ());
+                               sb.Append (":");
+                       }
+
+                       DoPath (sb, this);
+                       sb.Append ("}");
+
+                       return sb.ToString ();
+               }
+       }
+
+       //
+       // CaptureContext objects are created on demand if a method has
+       // anonymous methods and kept on the ToplevelBlock.
+       //
+       // If they exist, all ToplevelBlocks in the containing block are
+       // linked together (children pointing to their parents).
+       //
+       public class CaptureContext {
+               public static int count;
+               public int cc_id;
+               Location loc;
+               
+               //
+               // Points to the toplevel block that owns this CaptureContext
+               //
+               ToplevelBlock toplevel_owner;
+               Hashtable scopes = new Hashtable ();
+               bool have_captured_vars = false;
+               ScopeInfo topmost = null;
+
+               //
+               // Captured fields
+               //
+               Hashtable captured_fields = new Hashtable ();
+               Hashtable captured_variables = new Hashtable ();
+               public Hashtable captured_parameters = new Hashtable ();
+               public AnonymousMethod Host;
+               
+               public CaptureContext (ToplevelBlock toplevel_owner, Location loc, AnonymousMethod host)
+               {
+                       cc_id = count++;
+                       this.toplevel_owner = toplevel_owner;
+                       this.loc = loc;
+
+                       if (host != null)
+                               Host = host;
+               }
+
+               void DoPath (StringBuilder sb, CaptureContext cc)
+               {
+                       if (cc.ParentCaptureContext != null){
+                               DoPath (sb, cc.ParentCaptureContext);
+                               sb.Append (".");
+                       }
+                       sb.Append (cc_id.ToString ());
+               }
+               
+               public override string ToString ()
+               {
+                       ToplevelBlock parent = ParentToplevel;
+                       StringBuilder sb = new StringBuilder ();
+
+                       sb.Append ("[");
+                       DoPath (sb, this);
+                       sb.Append ("]");
+                       return sb.ToString ();
+               }
+
+               public ToplevelBlock ParentToplevel {
+                       get {
+                               return toplevel_owner.Container;
+                       }
+               }
+
+               public CaptureContext ParentCaptureContext {
+                       get {
+                               ToplevelBlock parent = ParentToplevel;
+                               
+                               return (parent == null) ? null : parent.CaptureContext;
+                       }
+               }
+
+               // Returns the deepest of two scopes
+               public ScopeInfo Deepest (ScopeInfo a, ScopeInfo b)
+               {
+                       ScopeInfo p;
+
+                       if (a == null)
+                               return b;
+                       if (b == null)
+                               return a;
+                       if (a == b)
+                               return a;
+
+                       //
+                       // If they Scopes are on the same CaptureContext, we do the double
+                       // checks just so if there is an invariant change in the future,
+                       // we get the exception at the end
+                       //
+                       for (p = a; p != null; p = p.ParentScope)
+                               if (p == b)
+                                       return a;
+                       
+                       for (p = b; p != null; p = p.ParentScope)
+                               if (p == a)
+                                       return b;
+
+                       CaptureContext ca = a.CaptureContext;
+                       CaptureContext cb = b.CaptureContext;
+
+                       for (CaptureContext c = ca; c != null; c = c.ParentCaptureContext)
+                               if (c == cb)
+                                       return a;
+
+                       for (CaptureContext c = cb; c != null; c = c.ParentCaptureContext)
+                               if (c == ca)
+                                       return b;
+                       throw new Exception ("Should never be reached");
+               }
+
+               void AdjustMethodScope (AnonymousMethod am, ScopeInfo scope)
+               {
+                       am.Scope = Deepest (am.Scope, scope);
+               }
+
+               void LinkScope (ScopeInfo scope, int id)
+               {
+                       ScopeInfo parent = (ScopeInfo) scopes [id];
+                       scope.ParentScope = parent;
+                       parent.AddChild (scope);
+
+                       if (scope == topmost)
+                               topmost = parent;
+               }
+               
+               public void AddLocal (AnonymousMethod am, LocalInfo li)
+               {
+                       if (li.Block.Toplevel != toplevel_owner){
+                               ParentCaptureContext.AddLocal (am, li);
+                               return;
+                       }
+                       int block_id = li.Block.ID;
+                       ScopeInfo scope;
+                       if (scopes [block_id] == null){
+                               scope = new ScopeInfo (this, li.Block);
+                               scopes [block_id] = scope;
+                       } else
+                               scope = (ScopeInfo) scopes [block_id];
+
+                       if (topmost == null){
+                               topmost = scope;
+                       } else {
+                               // Link to parent
+                               for (Block b = scope.ScopeBlock.Parent; b != null; b = b.Parent){
+                                       if (scopes [b.ID] != null){
+                                               LinkScope (scope, b.ID);
+                                               break;
+                                       }
+                               }
+
+                               if (scope.ParentScope == null && ParentCaptureContext != null){
+                                       CaptureContext pcc = ParentCaptureContext;
+                                       
+                                       for (Block b = am.ContainingBlock; b != null; b = b.Parent){
+                                               if (pcc.scopes [b.ID] != null){
+                                                       pcc.LinkScope (scope, b.ID);
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+
+                       //
+                       // Adjust the owner
+                       //
+                       if (Host != null)
+                               AdjustMethodScope (Host, topmost);
+
+                       //
+                       // Adjust the user
+                       //
+                       AdjustMethodScope (am, scope);
+                       
+                       if (captured_variables [li] != null)
+                               return;
+                       
+                       have_captured_vars = true;
+                       captured_variables [li] = li;
+                       scope.AddLocal (li);
+               }
+
+               //
+               // Retursn the CaptureContext for the block that defines the parameter `name'
+               //
+               static CaptureContext _ContextForParameter (ToplevelBlock current, string name)
+               {
+                       ToplevelBlock container = current.Container;
+                       if (container != null){
+                               CaptureContext cc = _ContextForParameter (container, name);
+                               if (cc != null)
+                                       return cc;
+                       }
+                       if (current.IsParameterReference (name))
+                               return current.ToplevelBlockCaptureContext;
+                       return null;
+               }
+
+               static CaptureContext ContextForParameter (ToplevelBlock current, string name)
+               {
+                       CaptureContext cc = _ContextForParameter (current, name);
+                       if (cc == null)
+                               throw new Exception (String.Format ("request for parameteter {0} failed: not found", name));
+                       return cc;
+               }
+               
+               //
+               // Records the captured parameter at the appropriate CaptureContext
+               //
+               public void AddParameter (EmitContext ec, AnonymousMethod am, string name, Type t, int idx)
+               {
+                       CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
+
+                       cc.AddParameterToContext (am, name, t, idx);
+               }
+
+               //
+               // Records the parameters in the context
+               //
+               void AddParameterToContext (AnonymousMethod am, string name, Type t, int idx)
+               {
+                       if (captured_parameters == null)
+                               captured_parameters = new Hashtable ();
+                       if (captured_parameters [name] != null)
+                               return;
+                       captured_parameters [name] = new CapturedParameter (t, idx);
+
+                       if (topmost == null){
+                               //
+                               // Create one ScopeInfo, if there are none.
+                               //
+                               topmost = new ScopeInfo (this, toplevel_owner);
+                               scopes [toplevel_owner.ID] = topmost;
+                       } else {
+                               //
+                               // If the topmost ScopeInfo is not at the topblock level, insert
+                               // a new ScopeInfo there.
+                               //
+                               if (topmost.ScopeBlock != toplevel_owner){
+                                       ScopeInfo par_si = new ScopeInfo (this, toplevel_owner);
+                                       scopes [toplevel_owner.ID] = topmost;
+                                       topmost.ParentScope = par_si;
+                                       topmost = par_si;
+                               }
+                       }
+                       
+                       topmost.HostsParameters = true;
+                       AdjustMethodScope (am, topmost);
+               }
+
+               //
+               // Captured fields are only recorded on the topmost CaptureContext, because that
+               // one is the one linked to the owner of instance fields
+               //
+               public void AddField (FieldExpr fe)
+               {
+                       if (fe.FieldInfo.IsStatic)
+                               throw new Exception ("Attempt to register a static field as a captured field");
+                       
+                       CaptureContext parent = ParentCaptureContext;
+                       if (parent != null)
+                               parent.AddField (fe);
+                       else
+                               captured_fields [fe] = fe;
+               }
+               
+
+               public bool HaveCapturedVariables {
+                       get {
+                               return have_captured_vars;
+                       }
+               }
+               
+               public bool HaveCapturedFields {
+                       get {
+                               CaptureContext parent = ParentCaptureContext;
+                               if (parent != null)
+                                       return parent.HaveCapturedFields;
+                               return captured_fields.Count > 0;
+                       }
+               }
+
+               public bool IsCaptured (LocalInfo local)
+               {
+                       foreach (ScopeInfo si in scopes.Values){
+                               if (si.IsCaptured (local))
+                                       return true;
+                       }
+                       return false;
+               }
+
+               //
+               // Returns whether the parameter is captured
+               //
+               public bool IsParameterCaptured (string name)
+               {
+                       if (ParentCaptureContext != null && ParentCaptureContext.IsParameterCaptured (name))
+                               return true;
+                       
+                       if (captured_parameters != null)
+                               return captured_parameters [name] != null;
+                       return false;
+               }
+
+               public void EmitHelperClasses (EmitContext ec)
+               {
+                       if (topmost != null){
+                               topmost.NeedThis = HaveCapturedFields;
+                               topmost.EmitScopeType (ec);
+                       } 
+               }
+
+               public void CloseHelperClasses ()
+               {
+                       if (topmost != null)
+                               topmost.CloseTypes ();
+               }
+
+               ScopeInfo GetScopeFromBlock (EmitContext ec, Block b)
+               {
+                       ScopeInfo si;
+                       
+                       si = (ScopeInfo) scopes [b.ID];
+                       if (si == null)
+                               throw new Exception ("Si is null for block " + b.ID);
+                       si.EmitInitScope (ec);
+
+                       return si;
+               }
+
+               //
+               // Emits the opcodes necessary to load the instance of the captured
+               // variable in `li'
+               //
+               public void EmitCapturedVariableInstance (EmitContext ec, LocalInfo li, AnonymousMethod am)
+               {
+                       ILGenerator ig = ec.ig;
+                       ScopeInfo si;
+                       
+                       if (li.Block.Toplevel == toplevel_owner){
+                               si = GetScopeFromBlock (ec, li.Block);
+                               ig.Emit (OpCodes.Ldloc, si.ScopeInstance);
+                               return;
+                       }
+
+                       si = am.Scope;
+                       ig.Emit (OpCodes.Ldarg_0);
+                       if (si != null){
+                               while (si.ScopeBlock.ID != li.Block.ID){
+                                       if (si.ParentLink != null)
+                                               ig.Emit (OpCodes.Ldfld, si.ParentLink);
+                                       si = si.ParentScope;
+                                       if (si == null) 
+                                               throw new Exception (
+                                                            String.Format ("Never found block {0} starting at {1} while looking up {2}",
+                                                                           li.Block.ID, am.Scope.ScopeBlock.ID, li.Name));
+                               }
+                       }
+               }
+
+               //
+               // Internal routine that loads the instance to reach parameter `name'
+               //
+               void EmitParameterInstance (EmitContext ec, string name)
+               {
+                       CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
+                       if (cc != this){
+                               cc.EmitParameterInstance (ec, name);
+                               return;
+                       }
+                       Block invocation_block = ec.CurrentBlock;
+                       CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
+                       ILGenerator ig = ec.ig;
+
+                       ScopeInfo si;
+                       if (ec.CurrentBlock == toplevel_owner){
+                               si = GetScopeFromBlock (ec, toplevel_owner);
+                               ig.Emit (OpCodes.Ldloc, si.ScopeInstance);
+                               return;
+                       }
+                       
+                       si = ec.CurrentAnonymousMethod.Scope;
+                       ig.Emit (OpCodes.Ldarg_0);
+                       if (si != null){
+                               while (si.ParentLink != null) {
+                                       ig.Emit (OpCodes.Ldfld, si.ParentLink);
+                                       si = si.ParentScope;
+                               } 
+                       }
+               }
+
+               //
+               // Emits the code necessary to load the parameter named `name' within
+               // an anonymous method.
+               //
+               public void EmitParameter (EmitContext ec, string name)
+               {
+                       CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
+                       if (cc != this){
+                               cc.EmitParameter (ec, name);
+                               return;
+                       }
+                       EmitParameterInstance (ec, name);
+                       CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
+                       ec.ig.Emit (OpCodes.Ldfld, par_info.FieldBuilder);
+               }
+
+               //
+               // Implements the assignment of `source' to the paramenter named `name' within
+               // an anonymous method.
+               //
+               public void EmitAssignParameter (EmitContext ec, string name, Expression source, bool leave_copy, bool prepare_for_load)
+               {
+                       CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
+                       if (cc != this){
+                               cc.EmitAssignParameter (ec, name, source, leave_copy, prepare_for_load);
+                               return;
+                       }
+                       ILGenerator ig = ec.ig;
+                       CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
+
+                       EmitParameterInstance (ec, name);
+                       source.Emit (ec);
+                       if (leave_copy)
+                               ig.Emit (OpCodes.Dup);
+                       ig.Emit (OpCodes.Stfld, par_info.FieldBuilder);
+               }
+
+               //
+               // Emits the address for the parameter named `name' within
+               // an anonymous method.
+               //
+               public void EmitAddressOfParameter (EmitContext ec, string name)
+               {
+                       CaptureContext cc = ContextForParameter (ec.CurrentBlock.Toplevel, name);
+                       if (cc != this){
+                               cc.EmitAddressOfParameter (ec, name);
+                               return;
+                       }
+                       EmitParameterInstance (ec, name);
+                       CapturedParameter par_info = (CapturedParameter) captured_parameters [name];
+                       ec.ig.Emit (OpCodes.Ldflda, par_info.FieldBuilder);
+               }
+
+               //
+               // The following methods are only invoked on the host for the
+               // anonymous method.
+               //
+               public void EmitMethodHostInstance (EmitContext target, AnonymousMethod am)
+               {
+                       ILGenerator ig = target.ig;
+                       ScopeInfo si = am.Scope;
+                       
+                       if (si == null){
+                               ig.Emit (OpCodes.Ldarg_0);
+                               return;
+                       }
+
+                       si.EmitInitScope (target);
+                       ig.Emit (OpCodes.Ldloc, si.ScopeInstance);
+               }
+
+               ArrayList all_scopes = new ArrayList ();
+               
+               public void AddScope (ScopeInfo si)
+               {
+                       all_scopes.Add (si);
+                       toplevel_owner.RegisterCaptureContext (this);
+               }
+
+               //
+               // Links any scopes that were not linked previously
+               //
+               public void AdjustScopes ()
+               {
+                       foreach (ScopeInfo scope in all_scopes){
+                               if (scope.ParentScope != null)
+                                       continue;
+
+                               for (Block b = scope.ScopeBlock.Parent; b != null; b = b.Parent){
+                                       if (scopes [b.ID] != null){
+                                               LinkScope (scope, b.ID);
+                                               break;
+                                       }
+                               }
+
+                               if (scope.ParentScope == null && ParentCaptureContext != null){
+                                       CaptureContext pcc = ParentCaptureContext;
+                                       
+                                       for (Block b = Host.ContainingBlock; b != null; b = b.Parent){
+                                               if (pcc.scopes [b.ID] != null){
+                                                       pcc.LinkScope (scope, b.ID);
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+}
diff --git a/mcs/bmcs/assign.cs b/mcs/bmcs/assign.cs
new file mode 100644 (file)
index 0000000..6c5c87d
--- /dev/null
@@ -0,0 +1,632 @@
+//
+// assign.cs: Assignments.
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//   Martin Baulig (martin@ximian.com)
+//
+// (C) 2001, 2002, 2003 Ximian, Inc.
+// (C) 2004 Novell, Inc
+//
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace Mono.CSharp {
+
+       /// <summary>
+       ///   This interface is implemented by expressions that can be assigned to.
+       /// </summary>
+       /// <remarks>
+       ///   This interface is implemented by Expressions whose values can not
+       ///   store the result on the top of the stack.
+       ///
+       ///   Expressions implementing this (Properties, Indexers and Arrays) would
+       ///   perform an assignment of the Expression "source" into its final
+       ///   location.
+       ///
+       ///   No values on the top of the stack are expected to be left by
+       ///   invoking this method.
+       /// </remarks>
+       public interface IAssignMethod {
+               //
+               // This is an extra version of Emit. If leave_copy is `true'
+               // A copy of the expression will be left on the stack at the
+               // end of the code generated for EmitAssign
+               //
+               void Emit (EmitContext ec, bool leave_copy);
+               
+               //
+               // This method does the assignment
+               // `source' will be stored into the location specified by `this'
+               // if `leave_copy' is true, a copy of `source' will be left on the stack
+               // if `prepare_for_load' is true, when `source' is emitted, there will
+               // be data on the stack that it can use to compuatate its value. This is
+               // for expressions like a [f ()] ++, where you can't call `f ()' twice.
+               //
+               void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load);
+               
+               /*
+               For simple assignments, this interface is very simple, EmitAssign is called with source
+               as the source expression and leave_copy and prepare_for_load false.
+               
+               For compound assignments it gets complicated.
+               
+               EmitAssign will be called as before, however, prepare_for_load will be
+               true. The @source expression will contain an expression
+               which calls Emit. So, the calls look like:
+               
+               this.EmitAssign (ec, source, false, true) ->
+                       source.Emit (ec); ->
+                               [...] ->
+                                       this.Emit (ec, false); ->
+                                       end this.Emit (ec, false); ->
+                               end [...]
+                       end source.Emit (ec);
+               end this.EmitAssign (ec, source, false, true)
+               
+               
+               When prepare_for_load is true, EmitAssign emits a `token' on the stack that
+               Emit will use for its state.
+               
+               Let's take FieldExpr as an example. assume we are emitting f ().y += 1;
+               
+               Here is the call tree again. This time, each call is annotated with the IL
+               it produces:
+               
+               this.EmitAssign (ec, source, false, true)
+                       call f
+                       dup
+                       
+                       Binary.Emit ()
+                               this.Emit (ec, false);
+                               ldfld y
+                               end this.Emit (ec, false);
+                               
+                               IntConstant.Emit ()
+                               ldc.i4.1
+                               end IntConstant.Emit
+                               
+                               add
+                       end Binary.Emit ()
+                       
+                       stfld
+               end this.EmitAssign (ec, source, false, true)
+               
+               Observe two things:
+                       1) EmitAssign left a token on the stack. It was the result of f ().
+                       2) This token was used by Emit
+               
+               leave_copy (in both EmitAssign and Emit) tells the compiler to leave a copy
+               of the expression at that point in evaluation. This is used for pre/post inc/dec
+               and for a = x += y. Let's do the above example with leave_copy true in EmitAssign
+               
+               this.EmitAssign (ec, source, true, true)
+                       call f
+                       dup
+                       
+                       Binary.Emit ()
+                               this.Emit (ec, false);
+                               ldfld y
+                               end this.Emit (ec, false);
+                               
+                               IntConstant.Emit ()
+                               ldc.i4.1
+                               end IntConstant.Emit
+                               
+                               add
+                       end Binary.Emit ()
+                       
+                       dup
+                       stloc temp
+                       stfld
+                       ldloc temp
+               end this.EmitAssign (ec, source, true, true)
+               
+               And with it true in Emit
+               
+               this.EmitAssign (ec, source, false, true)
+                       call f
+                       dup
+                       
+                       Binary.Emit ()
+                               this.Emit (ec, true);
+                               ldfld y
+                               dup
+                               stloc temp
+                               end this.Emit (ec, true);
+                               
+                               IntConstant.Emit ()
+                               ldc.i4.1
+                               end IntConstant.Emit
+                               
+                               add
+                       end Binary.Emit ()
+                       
+                       stfld
+                       ldloc temp
+               end this.EmitAssign (ec, source, false, true)
+               
+               Note that these two examples are what happens for ++x and x++, respectively.
+               */
+       }
+
+       /// <summary>
+       ///   An Expression to hold a temporary value.
+       /// </summary>
+       /// <remarks>
+       ///   The LocalTemporary class is used to hold temporary values of a given
+       ///   type to "simulate" the expression semantics on property and indexer
+       ///   access whose return values are void.
+       ///
+       ///   The local temporary is used to alter the normal flow of code generation
+       ///   basically it creates a local variable, and its emit instruction generates
+       ///   code to access this value, return its address or save its value.
+       ///
+       ///   If `is_address' is true, then the value that we store is the address to the
+       ///   real value, and not the value itself. 
+       ///
+       ///   This is needed for a value type, because otherwise you just end up making a
+       ///   copy of the value on the stack and modifying it. You really need a pointer
+       ///   to the origional value so that you can modify it in that location. This
+       ///   Does not happen with a class because a class is a pointer -- so you always
+       ///   get the indirection.
+       ///
+       ///   The `is_address' stuff is really just a hack. We need to come up with a better
+       ///   way to handle it.
+       /// </remarks>
+       public class LocalTemporary : Expression, IMemoryLocation {
+               LocalBuilder builder;
+               bool is_address;
+               
+               public LocalTemporary (EmitContext ec, Type t) : this (ec, t, false) {}
+                       
+               public LocalTemporary (EmitContext ec, Type t, bool is_address) 
+               {
+                       type = t;
+                       eclass = ExprClass.Value;
+                       loc = Location.Null;
+                       builder = ec.GetTemporaryLocal (is_address ? TypeManager.GetReferenceType (t): t);
+                       this.is_address = is_address;
+               }
+
+               public LocalTemporary (LocalBuilder b, Type t)
+               {
+                       type = t;
+                       eclass = ExprClass.Value;
+                       loc = Location.Null;
+                       builder = b;
+               }
+
+               public void Release (EmitContext ec)
+               {
+                       ec.FreeTemporaryLocal (builder, type);
+                       builder = null;
+               }
+               
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       ig.Emit (OpCodes.Ldloc, builder);
+                       // we need to copy from the pointer
+                       if (is_address)
+                               LoadFromPtr (ig, type);
+               }
+
+               // NB: if you have `is_address' on the stack there must
+               // be a managed pointer. Otherwise, it is the type from
+               // the ctor.
+               public void Store (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       ig.Emit (OpCodes.Stloc, builder);
+               }
+
+               public void AddressOf (EmitContext ec, AddressOp mode)
+               {
+                       // if is_address, than this is just the address anyways,
+                       // so we just return this.
+                       ILGenerator ig = ec.ig;
+                               
+                       if (is_address)
+                               ig.Emit (OpCodes.Ldloc, builder);
+                       else
+                               ig.Emit (OpCodes.Ldloca, builder);
+               }
+
+               public bool PointsToAddress {
+                       get {
+                               return is_address;
+                       }
+               }
+       }
+
+       /// <summary>
+       ///   The Assign node takes care of assigning the value of source into
+       ///   the expression represented by target. 
+       /// </summary>
+       public class Assign : ExpressionStatement {
+               protected Expression target, source, real_source;
+               protected LocalTemporary temp = null, real_temp = null;
+               protected Assign embedded = null;
+               protected bool is_embedded = false;
+               protected bool must_free_temp = false;
+
+               public Assign (Expression target, Expression source, Location l)
+               {
+                       this.target = target;
+                       this.source = this.real_source = source;
+                       this.loc = l;
+               }
+
+               protected Assign (Assign embedded, Location l)
+                       : this (embedded.target, embedded.source, l)
+               {
+                       this.is_embedded = true;
+               }
+
+               protected virtual Assign GetEmbeddedAssign (Location loc)
+               {
+                       return new Assign (this, loc);
+               }
+
+               public Expression Target {
+                       get {
+                               return target;
+                       }
+
+                       set {
+                               target = value;
+                       }
+               }
+
+               public Expression Source {
+                       get {
+                               return source;
+                       }
+
+                       set {
+                               source = value;
+                       }
+               }
+
+               public static void error70 (EventInfo ei, Location l)
+               {
+                       Report.Error (70, l, "The event '" + ei.Name +
+                                     "' can only appear on the left-side of a += or -= (except when" +
+                                     " used from within the type '" + ei.DeclaringType + "')");
+               }
+
+               //
+               // Will return either `this' or an instance of `New'.
+               //
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       // Create an embedded assignment if our source is an assignment.
+                       if (source is Assign)
+                               source = embedded = ((Assign) source).GetEmbeddedAssign (loc);
+
+                       real_source = source = source.Resolve (ec);
+                       if (source == null)
+                               return null;
+
+                       //
+                       // This is used in an embedded assignment.
+                       // As an example, consider the statement "A = X = Y = Z".
+                       //
+                       if (is_embedded && !(source is Constant)) {
+                               // If this is the innermost assignment (the "Y = Z" in our example),
+                               // create a new temporary local, otherwise inherit that variable
+                               // from our child (the "X = (Y = Z)" inherits the local from the
+                               // "Y = Z" assignment).
+
+                               if (embedded == null) {
+                                       if (this is CompoundAssign)
+                                               real_temp = temp = new LocalTemporary (ec, target.Type);
+                                       else
+                                               real_temp = temp = new LocalTemporary (ec, source.Type);
+                               } else
+                                       temp = embedded.temp;
+
+                               // Set the source to the new temporary variable.
+                               // This means that the following target.ResolveLValue () will tell
+                               // the target to read it's source value from that variable.
+                               source = temp;
+                       }
+
+                       // If we have an embedded assignment, use the embedded assignment's temporary
+                       // local variable as source.
+                       if (embedded != null)
+                               source = (embedded.temp != null) ? embedded.temp : embedded.source;
+
+                       target = target.ResolveLValue (ec, source);
+
+                       if (target == null)
+                               return null;
+
+                       Type target_type = target.Type;
+                       Type source_type = real_source.Type;
+
+                       // If we're an embedded assignment, our parent will reuse our source as its
+                       // source, it won't read from our target.
+                       if (is_embedded)
+                               type = source_type;
+                       else
+                               type = target_type;
+                       eclass = ExprClass.Value;
+
+                       if (target is EventExpr) {
+                               EventInfo ei = ((EventExpr) target).EventInfo;
+
+                               Expression ml = MemberLookup (
+                                       ec, ec.ContainerType, ei.Name,
+                                       MemberTypes.Event, AllBindingFlags | BindingFlags.DeclaredOnly, loc);
+
+                               if (ml == null) {
+                                       //
+                                       // If this is the case, then the Event does not belong 
+                                       // to this Type and so, according to the spec
+                                       // is allowed to only appear on the left hand of
+                                       // the += and -= operators
+                                       //
+                                       // Note that target will not appear as an EventExpr
+                                       // in the case it is being referenced within the same type container;
+                                       // it will appear as a FieldExpr in that case.
+                                       //
+                                       
+                                       if (!(source is BinaryDelegate)) {
+                                               error70 (ei, loc);
+                                               return null;
+                                       } 
+                               }
+                       }
+
+                       FieldExpr field_exp = target as FieldExpr;
+                       if (field_exp != null && !ec.IsConstructor && !ec.IsFieldInitializer) {
+                               field_exp = field_exp.InstanceExpression as FieldExpr;
+                               if (field_exp != null && field_exp.FieldInfo.IsInitOnly) {
+                                       if (field_exp.IsStatic) {
+                                               Report.Error (1650, loc, "Members of static readonly field '{0}' cannot be assigned to " +
+                                                       "(except in a static constructor or a variable initializer)", TypeManager.GetFullNameSignature (field_exp.FieldInfo));
+                                       } else {
+                                               Report.Error (1648, loc, "Members of readonly field '{0}' cannot be assigned to " +
+                                                       "(except in a constructor or a variable initializer)", TypeManager.GetFullNameSignature (field_exp.FieldInfo));
+                                       }
+                                       return null;
+                               }
+                       }
+
+                       if (!(target is IAssignMethod) && (target.eclass != ExprClass.EventAccess)) {
+                               Report.Error (131, loc,
+                                             "Left hand of an assignment must be a variable, " +
+                                             "a property or an indexer");
+                               return null;
+                       }
+
+                       if ((source.eclass == ExprClass.Type) && (source is TypeExpr)) {
+                               source.Error_UnexpectedKind ("variable or value", loc);
+                               return null;
+                       } else if ((RootContext.Version == LanguageVersion.ISO_1) &&
+                                  (source is MethodGroupExpr)){
+                               ((MethodGroupExpr) source).ReportUsageError ();
+                               return null;
+
+                       }
+
+                       if (target_type == source_type){
+                       if (source is New && target_type.IsValueType &&
+                           (target.eclass != ExprClass.IndexerAccess) && (target.eclass != ExprClass.PropertyAccess)){
+                               New n = (New) source;
+
+                               if (n.SetValueTypeVariable (target))
+                                       return n;
+                               else
+                                       return null;
+                       }
+
+                               return this;
+                       }
+
+                       //
+                       // If this assignemnt/operator was part of a compound binary
+                       // operator, then we allow an explicit conversion, as detailed
+                       // in the spec. 
+                       //
+
+                       if (this is CompoundAssign){
+                               CompoundAssign a = (CompoundAssign) this;
+                               
+                               Binary b = source as Binary;
+                               if (b != null){
+                                       //
+                                       // 1. if the source is explicitly convertible to the
+                                       //    target_type
+                                       //
+                                       
+                                       source = Convert.ExplicitConversion (ec, source, target_type, loc);
+                                       if (source == null){
+                                               Convert.Error_CannotImplicitConversion (loc, source_type, target_type);
+                                               return null;
+                                       }
+                               
+                                       //
+                                       // 2. and the original right side is implicitly convertible to
+                                       // the type of target
+                                       //
+                                       if (Convert.ImplicitStandardConversionExists (ec, a.original_source, target_type))
+                                               return this;
+
+                                       //
+                                       // In the spec 2.4 they added: or if type of the target is int
+                                       // and the operator is a shift operator...
+                                       //
+                                       if (source_type == TypeManager.int32_type &&
+                                           (b.Oper == Binary.Operator.LeftShift || b.Oper == Binary.Operator.RightShift))
+                                               return this;
+
+                                       Convert.Error_CannotImplicitConversion (loc, a.original_source.Type, target_type);
+                                       return null;
+                               }
+                       }
+
+                       source = Convert.ImplicitConversionRequired (ec, source, target_type, loc);
+                       if (source == null)
+                               return null;
+
+                       // If we're an embedded assignment, we need to create a new temporary variable
+                       // for the converted value.  Our parent will use this new variable as its source.
+                       // The same applies when we have an embedded assignment - in this case, we need
+                       // to convert our embedded assignment's temporary local variable to the correct
+                       // type and store it in a new temporary local.
+                       if (is_embedded || embedded != null) {
+                               type = target_type;
+                               temp = new LocalTemporary (ec, type);
+                               must_free_temp = true;
+                       }
+                       
+                       return this;
+               }
+
+               Expression EmitEmbedded (EmitContext ec)
+               {
+                       // Emit an embedded assignment.
+
+                       if (real_temp != null) {
+                               // If we're the innermost assignment, `real_source' is the right-hand
+                               // expression which gets assigned to all the variables left of it.
+                               // Emit this expression and store its result in real_temp.
+                               real_source.Emit (ec);
+                               real_temp.Store (ec);
+                       }
+
+                       if (embedded != null)
+                               embedded.EmitEmbedded (ec);
+
+                       // This happens when we've done a type conversion, in this case source will be
+                       // the expression which does the type conversion from real_temp.
+                       // So emit it and store the result in temp; this is the var which will be read
+                       // by our parent.
+                       if (temp != real_temp) {
+                               source.Emit (ec);
+                               temp.Store (ec);
+                       }
+
+                       Expression temp_source = (temp != null) ? temp : source;
+                       ((IAssignMethod) target).EmitAssign (ec, temp_source, false, false);
+                       return temp_source;
+               }
+
+               void ReleaseEmbedded (EmitContext ec)
+               {
+                       if (embedded != null)
+                               embedded.ReleaseEmbedded (ec);
+
+                       if (real_temp != null)
+                               real_temp.Release (ec);
+
+                       if (must_free_temp)
+                               temp.Release (ec);
+               }
+
+               void Emit (EmitContext ec, bool is_statement)
+               {
+                       if (target is EventExpr) {
+                               ((EventExpr) target).EmitAddOrRemove (ec, source);
+                               return;
+                       }
+                       
+                       IAssignMethod am = (IAssignMethod) target;
+
+                       Expression temp_source;
+                       if (embedded != null) {
+                               temp_source = embedded.EmitEmbedded (ec);
+
+                               if (temp != null) {
+                                       source.Emit (ec);
+                                       temp.Store (ec);
+                                       temp_source = temp;
+                               }
+                       } else
+                               temp_source = source;
+               
+                       am.EmitAssign (ec, temp_source, !is_statement, this is CompoundAssign);
+                               
+                       if (embedded != null) {
+                               if (temp != null)
+                                       temp.Release (ec);
+                               embedded.ReleaseEmbedded (ec);
+                       }
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       Emit (ec, false);
+               }
+
+               public override void EmitStatement (EmitContext ec)
+               {
+                       Emit (ec, true);
+               }
+       }
+
+       
+       //
+       // This class is used for compound assignments.  
+       //
+       class CompoundAssign : Assign {
+               Binary.Operator op;
+               public Expression original_source;
+               
+               public CompoundAssign (Binary.Operator op, Expression target, Expression source, Location l)
+                       : base (target, source, l)
+               {
+                       original_source = source;
+                       this.op = op;
+               }
+
+               protected CompoundAssign (CompoundAssign embedded, Location l)
+                       : this (embedded.op, embedded.target, embedded.source, l)
+               {
+                       this.is_embedded = true;
+               }
+
+               protected override Assign GetEmbeddedAssign (Location loc)
+               {
+                       return new CompoundAssign (this, loc);
+               }
+
+               public Expression ResolveSource (EmitContext ec)
+               {
+                       return original_source.Resolve (ec);
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       original_source = original_source.Resolve (ec);
+                       if (original_source == null)
+                               return null;
+
+                       target = target.Resolve (ec);
+                       if (target == null)
+                               return null;
+                       
+                       //
+                       // Only now we can decouple the original source/target
+                       // into a tree, to guarantee that we do not have side
+                       // effects.
+                       //
+                       source = new Binary (op, target, original_source, loc);
+                       return base.DoResolve (ec);
+               }
+       }
+}
+
+
+
+
diff --git a/mcs/bmcs/attribute.cs b/mcs/bmcs/attribute.cs
new file mode 100644 (file)
index 0000000..7c68244
--- /dev/null
@@ -0,0 +1,1610 @@
+//
+// attribute.cs: Attribute Handler
+//
+// Author: Ravi Pratap (ravi@ximian.com)
+//         Marek Safar (marek.safar@seznam.cz)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+//
+//
+
+using System;
+using System.Diagnostics;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices;
+using System.Runtime.CompilerServices;
+using System.Security; 
+using System.Security.Permissions;
+using System.Text;
+
+namespace Mono.CSharp {
+
+       /// <summary>
+       ///   Base class for objects that can have Attributes applied to them.
+       /// </summary>
+       public abstract class Attributable {
+               /// <summary>
+               ///   Attributes for this type
+               /// </summary>
+               protected Attributes attributes;
+
+               public Attributable (Attributes attrs)
+               {
+                       attributes = attrs;
+               }
+
+               public Attributes OptAttributes 
+               {
+                       get {
+                               return attributes;
+                       }
+                       set {
+                               attributes = value;
+                       }
+               }
+
+               /// <summary>
+               /// Use member-specific procedure to apply attribute @a in @cb to the entity being built in @builder
+               /// </summary>
+               public abstract void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb);
+
+               /// <summary>
+               /// Returns one AttributeTarget for this element.
+               /// </summary>
+               public abstract AttributeTargets AttributeTargets { get; }
+
+               public abstract bool IsClsCompliaceRequired (DeclSpace ds);
+
+               /// <summary>
+               /// Gets list of valid attribute targets for explicit target declaration.
+               /// The first array item is default target. Don't break this rule.
+               /// </summary>
+               public abstract string[] ValidAttributeTargets { get; }
+       };
+
+       public class Attribute {
+               public readonly string ExplicitTarget;
+               public AttributeTargets Target;
+
+               public readonly string    Name;
+               public readonly ArrayList Arguments;
+
+               public readonly Location Location;
+
+               public Type Type;
+               
+               // Is non-null if type is AttributeUsageAttribute
+               AttributeUsageAttribute usage_attribute;
+
+               public AttributeUsageAttribute UsageAttribute {
+                       get {
+                               return usage_attribute;
+                       }
+               }
+               
+               MethodImplOptions ImplOptions;
+               UnmanagedType     UnmanagedType;
+               CustomAttributeBuilder cb;
+       
+               // non-null if named args present after Resolve () is called
+               PropertyInfo [] prop_info_arr;
+               FieldInfo [] field_info_arr;
+               object [] field_values_arr;
+               object [] prop_values_arr;
+               object [] pos_values;
+
+               static PtrHashtable usage_attr_cache = new PtrHashtable ();
+               
+               public Attribute (string target, string name, ArrayList args, Location loc)
+               {
+                       Name = name;
+                       Arguments = args;
+                       Location = loc;
+                       ExplicitTarget = target;
+               }
+
+               void Error_InvalidNamedArgument (string name)
+               {
+                       Report.Error (617, Location, "Invalid attribute argument: '{0}'.  Argument must be fields " +
+                                     "fields which are not readonly, static or const;  or read-write instance properties.",
+                                     Name);
+               }
+
+               static void Error_AttributeArgumentNotValid (Location loc)
+               {
+                       Report.Error (182, loc,
+                                     "An attribute argument must be a constant expression, typeof " +
+                                     "expression or array creation expression");
+               }
+
+               static void Error_TypeParameterInAttribute (Location loc)
+               {
+                       Report.Error (
+                               -202, loc, "Can not use a type parameter in an attribute");
+               }
+
+               /// <summary>
+               /// This is rather hack. We report many emit attribute error with same error to be compatible with
+               /// csc. But because csc has to report them this way because error came from ilasm we needn't.
+               /// </summary>
+               public void Error_AttributeEmitError (string inner)
+               {
+                       Report.Error (647, Location, "Error emitting '{0}' attribute because '{1}'", Name, inner);
+               }
+
+               public void Error_InvalidSecurityParent ()
+               {
+                       Error_AttributeEmitError ("it is attached to invalid parent");
+               }
+
+               void Error_AttributeConstructorMismatch ()
+               {
+                       Report.Error (-6, Location,
+                                      "Could not find a constructor for this argument list.");
+               }
+
+               /// <summary>
+                ///   Tries to resolve the type of the attribute. Flags an error if it can't, and complain is true.
+                /// </summary>
+               protected virtual Type CheckAttributeType (EmitContext ec)
+               {
+                       string NameAttribute = Name + "Attribute";
+                       Type t1 = ec.ResolvingTypeTree
+                               ? ec.DeclSpace.FindType (Location, Name)
+                               : RootContext.LookupType (ec.DeclSpace, Name, true, Location);
+
+                       // FIXME: Shouldn't do this for quoted attributes: [@A]
+                       Type t2 = ec.ResolvingTypeTree
+                               ? ec.DeclSpace.FindType (Location, NameAttribute)
+                               : RootContext.LookupType (ec.DeclSpace, NameAttribute, true, Location);
+
+                       String err0616 = null;
+                       if (t1 != null && ! t1.IsSubclassOf (TypeManager.attribute_type)) {
+                               t1 = null;
+                               err0616 = "'" + Name + "': is not an attribute class";
+                       }
+                       if (t2 != null && ! t2.IsSubclassOf (TypeManager.attribute_type)) {
+                               t2 = null;
+                               err0616 = (err0616 != null) 
+                                       ? "Neither '" + Name + "' nor '" + NameAttribute +"' is an attribute class"
+                                       : "'" + Name + "Attribute': is not an attribute class";
+                       }
+
+                       if (t1 != null && t2 != null) {
+                               Report.Error(1614, Location, "'" + Name + "': is ambiguous; " 
+                                            + " use either '@" + Name + "' or '" + NameAttribute + "'");
+                               return null;
+                       }
+                       if (t1 != null)
+                               return t1;
+                       if (t2 != null)
+                               return t2;
+                       if (err0616 != null) {
+                               Report.Error (616, Location, err0616);
+                               return null;
+                       }
+
+                       Report.Error (246, Location, 
+                                     "Could not find attribute '" + Name 
+                                     + "' (are you missing a using directive or an assembly reference ?)");
+
+                       return null;
+               }
+
+               public Type ResolveType (EmitContext ec)
+               {
+                       if (Type == null)
+                               Type = CheckAttributeType (ec);
+                       return Type;
+               }
+
+               /// <summary>
+               ///   Validates the guid string
+               /// </summary>
+               bool ValidateGuid (string guid)
+               {
+                       try {
+                               new Guid (guid);
+                               return true;
+                       } catch {
+                               Report.Error (647, Location, "Format of GUID is invalid: " + guid);
+                               return false;
+                       }
+               }
+
+               string GetFullMemberName (string member)
+               {
+                       return Type.FullName + '.' + member;
+               }
+
+               //
+               // Given an expression, if the expression is a valid attribute-argument-expression
+               // returns an object that can be used to encode it, or null on failure.
+               //
+               public static bool GetAttributeArgumentExpression (Expression e, Location loc, Type arg_type, out object result)
+               {
+                       if (e is EnumConstant) {
+                               if (RootContext.StdLib)
+                                       result = ((EnumConstant)e).GetValueAsEnumType ();
+                               else
+                                       result = ((EnumConstant)e).GetValue ();
+
+                               return true;
+                       }
+
+                       Constant constant = e as Constant;
+                       if (constant != null) {
+                               if (e.Type != arg_type) {
+                                       constant = Const.ChangeType (loc, constant, arg_type);
+                                       if (constant == null) {
+                                               result = null;
+                                               Error_AttributeArgumentNotValid (loc);
+                                               return false;
+                                       }
+                               }
+                               result = constant.GetValue ();
+                               return true;
+                       } else if (e is TypeOf) {
+                               result = ((TypeOf) e).TypeArg;
+                               return true;
+                       } else if (e is ArrayCreation){
+                               result =  ((ArrayCreation) e).EncodeAsAttribute ();
+                               if (result != null)
+                                       return true;
+                       } else if (e is EmptyCast) {
+                               Expression child = ((EmptyCast)e).Child;
+                               return GetAttributeArgumentExpression (child, loc, child.Type, out result);
+                       }
+
+                       result = null;
+                       Error_AttributeArgumentNotValid (loc);
+                       return false;
+               }
+               
+               public CustomAttributeBuilder Resolve (EmitContext ec)
+               {
+                       Type oldType = Type;
+                       
+                       // Sanity check.
+                       Type = CheckAttributeType (ec);
+
+                       if (oldType == null && Type == null)
+                               return null;
+                       if (oldType != null && oldType != Type){
+                               Report.Error (-27, Location,
+                                             "Attribute {0} resolved to different types at different times: {1} vs. {2}",
+                                             Name, oldType, Type);
+                               return null;
+                       }
+
+                       if (Type.IsAbstract) {
+                               Report.Error (653, Location, "Cannot apply attribute class '{0}' because it is abstract", Name);
+                               return null;
+                       }
+
+                       bool MethodImplAttr = false;
+                       bool MarshalAsAttr = false;
+                       bool GuidAttr = false;
+                       bool usage_attr = false;
+
+                       bool DoCompares = true;
+
+                        //
+                        // If we are a certain special attribute, we
+                        // set the information accordingly
+                        //
+                        
+                       if (Type == TypeManager.attribute_usage_type)
+                               usage_attr = true;
+                       else if (Type == TypeManager.methodimpl_attr_type)
+                               MethodImplAttr = true;
+                       else if (Type == TypeManager.marshal_as_attr_type)
+                               MarshalAsAttr = true;
+                       else if (Type == TypeManager.guid_attr_type)
+                               GuidAttr = true;
+                       else
+                               DoCompares = false;
+
+                       // Now we extract the positional and named arguments
+                       
+                       ArrayList pos_args = new ArrayList ();
+                       ArrayList named_args = new ArrayList ();
+                       int pos_arg_count = 0;
+                       
+                       if (Arguments != null) {
+                               pos_args = (ArrayList) Arguments [0];
+                               if (pos_args != null)
+                                       pos_arg_count = pos_args.Count;
+                               if (Arguments.Count > 1)
+                                       named_args = (ArrayList) Arguments [1];
+                       }
+
+                       pos_values = new object [pos_arg_count];
+
+                       //
+                       // First process positional arguments 
+                       //
+
+                       int i;
+                       for (i = 0; i < pos_arg_count; i++) {
+                               Argument a = (Argument) pos_args [i];
+                               Expression e;
+
+                               if (!a.Resolve (ec, Location))
+                                       return null;
+
+                               e = a.Expr;
+
+                               object val;
+                               if (!GetAttributeArgumentExpression (e, Location, a.Type, out val))
+                                       return null;
+                               
+                               pos_values [i] = val;
+
+                               if (DoCompares){
+                                       if (usage_attr) {
+                                               usage_attribute = new AttributeUsageAttribute ((AttributeTargets)val);
+                                       } else if (MethodImplAttr) {
+                                               this.ImplOptions = (MethodImplOptions) val;
+                                       } else if (GuidAttr){
+                                               //
+                                               // we will later check the validity of the type
+                                               //
+                                               if (val is string){
+                                                       if (!ValidateGuid ((string) val))
+                                                               return null;
+                                               }
+                                               
+                                       } else if (MarshalAsAttr)
+                                               this.UnmanagedType =
+                                               (System.Runtime.InteropServices.UnmanagedType) val;
+                               }
+                       }
+
+                       //
+                       // Now process named arguments
+                       //
+
+                       ArrayList field_infos = null;
+                       ArrayList prop_infos  = null;
+                       ArrayList field_values = null;
+                       ArrayList prop_values = null;
+
+                       if (named_args.Count > 0) {
+                               field_infos = new ArrayList ();
+                               prop_infos  = new ArrayList ();
+                               field_values = new ArrayList ();
+                               prop_values = new ArrayList ();
+                       }
+
+                       Hashtable seen_names = new Hashtable();
+                       
+                       for (i = 0; i < named_args.Count; i++) {
+                               DictionaryEntry de = (DictionaryEntry) named_args [i];
+                               string member_name = (string) de.Key;
+                               Argument a  = (Argument) de.Value;
+                               Expression e;
+
+                               if (seen_names.Contains(member_name)) {
+                                       Report.Error(643, Location, "'" + member_name + "' duplicate named attribute argument");
+                                       return null;
+                               }                               
+                               seen_names.Add(member_name, 1);
+                               
+                               if (!a.Resolve (ec, Location))
+                                       return null;
+
+                               Expression member = Expression.MemberLookup (
+                                       ec, Type, member_name,
+                                       MemberTypes.Field | MemberTypes.Property,
+                                       BindingFlags.Public | BindingFlags.Instance,
+                                       Location);
+
+                               if (member == null) {
+                                       member = Expression.MemberLookup (ec, Type, member_name,
+                                               MemberTypes.Field | MemberTypes.Property, BindingFlags.NonPublic | BindingFlags.Instance,
+                                               Location);
+
+                                       if (member != null) {
+                                               Report.Error (122, Location, "'{0}' is inaccessible due to its protection level", GetFullMemberName (member_name));
+                                               return null;
+                                       }
+                               }
+
+                               if (member == null){
+                                       Report.Error (117, Location, "Attribute `{0}' does not contain a definition for `{1}'",
+                                                     Type, member_name);
+                                       return null;
+                               }
+                               
+                               if (!(member is PropertyExpr || member is FieldExpr)) {
+                                       Error_InvalidNamedArgument (member_name);
+                                       return null;
+                               }
+
+                               e = a.Expr;
+                               if (e is TypeParameterExpr){
+                                       Error_TypeParameterInAttribute (Location);
+                                       return null;
+                               }
+                                       
+                               if (member is PropertyExpr) {
+                                       PropertyExpr pe = (PropertyExpr) member;
+                                       PropertyInfo pi = pe.PropertyInfo;
+
+                                       if (!pi.CanWrite || !pi.CanRead) {
+                                               Report.SymbolRelatedToPreviousError (pi);
+                                               Error_InvalidNamedArgument (member_name);
+                                               return null;
+                                       }
+
+                                       object value;
+                                       if (!GetAttributeArgumentExpression (e, Location, pi.PropertyType, out value))
+                                                               return null;
+                                               
+                                               if (usage_attribute != null) {
+                                                       if (member_name == "AllowMultiple")
+                                                       usage_attribute.AllowMultiple = (bool) value;
+                                                       if (member_name == "Inherited")
+                                                       usage_attribute.Inherited = (bool) value;
+                                       }
+                                       
+                                       prop_values.Add (value);
+                                       prop_infos.Add (pi);
+                                       
+                               } else if (member is FieldExpr) {
+                                       FieldExpr fe = (FieldExpr) member;
+                                       FieldInfo fi = fe.FieldInfo;
+
+                                       if (fi.IsInitOnly) {
+                                               Error_InvalidNamedArgument (member_name);
+                                               return null;
+                                       }
+
+                                       object value;
+                                       if (!GetAttributeArgumentExpression (e, Location, fi.FieldType, out value))
+                                               return null;
+
+                                       field_values.Add (value);
+
+                                       field_infos.Add (fi);
+                               }
+                       }
+
+                       Expression mg = Expression.MemberLookup (
+                               ec, Type, ".ctor", MemberTypes.Constructor,
+                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                                Location);
+
+                       if (mg == null) {
+                               Error_AttributeConstructorMismatch ();
+                               return null;
+                       }
+
+                       MethodBase constructor = Invocation.OverloadResolve (
+                               ec, (MethodGroupExpr) mg, pos_args, false, Location);
+
+                       if (constructor == null) {
+                               return null;
+                       }
+
+                       //
+                       // Now we perform some checks on the positional args as they
+                       // cannot be null for a constructor which expects a parameter
+                       // of type object
+                       //
+
+                       ParameterData pd = Invocation.GetParameterData (constructor);
+
+                       int last_real_param = pd.Count;
+                       if (pd.HasParams) {
+                               // When the params is not filled we need to put one
+                               if (last_real_param > pos_arg_count) {
+                                       object [] new_pos_values = new object [pos_arg_count + 1];
+                                       pos_values.CopyTo (new_pos_values, 0);
+                                       new_pos_values [pos_arg_count] = new object [] {} ;
+                                       pos_values = new_pos_values;
+                               }
+                               last_real_param--;
+                       }
+
+                       for (int j = 0; j < pos_arg_count; ++j) {
+                               Argument a = (Argument) pos_args [j];
+                               
+                               if (a.Expr is NullLiteral && pd.ParameterType (j) == TypeManager.object_type) {
+                                       Error_AttributeArgumentNotValid (Location);
+                                       return null;
+                               }
+
+                               if (j < last_real_param)
+                                       continue;
+                               
+                               if (j == last_real_param) {
+                                       object [] array = new object [pos_arg_count - last_real_param];
+                                       array [0] = pos_values [j];
+                                       pos_values [j] = array;
+                                       continue;
+                               }
+
+                               object [] params_array = (object []) pos_values [last_real_param];
+                               params_array [j - last_real_param] = pos_values [j];
+                       }
+
+                       // Adjust the size of the pos_values if it had params
+                       if (last_real_param != pos_arg_count) {
+                               object [] new_pos_values = new object [last_real_param + 1];
+                               Array.Copy (pos_values, new_pos_values, last_real_param + 1);
+                               pos_values = new_pos_values;
+                       }
+
+                       try {
+                               if (named_args.Count > 0) {
+                                       prop_info_arr = new PropertyInfo [prop_infos.Count];
+                                       field_info_arr = new FieldInfo [field_infos.Count];
+                                       field_values_arr = new object [field_values.Count];
+                                       prop_values_arr = new object [prop_values.Count];
+
+                                       field_infos.CopyTo  (field_info_arr, 0);
+                                       field_values.CopyTo (field_values_arr, 0);
+
+                                       prop_values.CopyTo  (prop_values_arr, 0);
+                                       prop_infos.CopyTo   (prop_info_arr, 0);
+
+                                       cb = new CustomAttributeBuilder (
+                                               (ConstructorInfo) constructor, pos_values,
+                                               prop_info_arr, prop_values_arr,
+                                               field_info_arr, field_values_arr);
+                               }
+                               else
+                                       cb = new CustomAttributeBuilder (
+                                               (ConstructorInfo) constructor, pos_values);
+                       } catch (NullReferenceException) {
+                               // 
+                               // Don't know what to do here
+                               //
+                               Report.Warning (
+                                       -101, Location, "NullReferenceException while trying to create attribute." +
+                                        "Something's wrong!");
+                       } catch (Exception e) {
+                               //
+                               // Sample:
+                               // using System.ComponentModel;
+                               // [DefaultValue (CollectionChangeAction.Add)]
+                               // class X { static void Main () {} }
+                               //
+                               Report.Warning (
+                                       -23, Location, "The compiler can not encode this attribute in .NET due to a bug in the .NET runtime. Try the Mono runtime. The exception was: " + e.Message);
+                       }
+                       
+                       return cb;
+               }
+
+               /// <summary>
+               ///   Get a string containing a list of valid targets for the attribute 'attr'
+               /// </summary>
+               public string GetValidTargets ()
+               {
+                       StringBuilder sb = new StringBuilder ();
+                       AttributeTargets targets = GetAttributeUsage ().ValidOn;
+
+                       if ((targets & AttributeTargets.Assembly) != 0)
+                               sb.Append ("'assembly' ");
+
+                       if ((targets & AttributeTargets.Class) != 0)
+                               sb.Append ("'class' ");
+
+                       if ((targets & AttributeTargets.Constructor) != 0)
+                               sb.Append ("'constructor' ");
+
+                       if ((targets & AttributeTargets.Delegate) != 0)
+                               sb.Append ("'delegate' ");
+
+                       if ((targets & AttributeTargets.Enum) != 0)
+                               sb.Append ("'enum' ");
+
+                       if ((targets & AttributeTargets.Event) != 0)
+                               sb.Append ("'event' ");
+
+                       if ((targets & AttributeTargets.Field) != 0)
+                               sb.Append ("'field' ");
+
+                       if ((targets & AttributeTargets.Interface) != 0)
+                               sb.Append ("'interface' ");
+
+                       if ((targets & AttributeTargets.Method) != 0)
+                               sb.Append ("'method' ");
+
+                       if ((targets & AttributeTargets.Module) != 0)
+                               sb.Append ("'module' ");
+
+                       if ((targets & AttributeTargets.Parameter) != 0)
+                               sb.Append ("'parameter' ");
+
+                       if ((targets & AttributeTargets.Property) != 0)
+                               sb.Append ("'property' ");
+
+                       if ((targets & AttributeTargets.ReturnValue) != 0)
+                               sb.Append ("'return' ");
+
+                       if ((targets & AttributeTargets.Struct) != 0)
+                               sb.Append ("'struct' ");
+
+                       return sb.ToString ();
+
+               }
+
+               /// <summary>
+               /// Returns AttributeUsage attribute for this type
+               /// </summary>
+               public AttributeUsageAttribute GetAttributeUsage ()
+               {
+                       AttributeUsageAttribute ua = usage_attr_cache [Type] as AttributeUsageAttribute;
+                       if (ua != null)
+                               return ua;
+
+                       Class attr_class = TypeManager.LookupClass (Type);
+
+                       if (attr_class == null) {
+                               object[] usage_attr = Type.GetCustomAttributes (TypeManager.attribute_usage_type, true);
+                               ua = (AttributeUsageAttribute)usage_attr [0];
+                               usage_attr_cache.Add (Type, ua);
+                               return ua;
+                       }
+               
+                       return attr_class.AttributeUsage;
+               }
+
+               /// <summary>
+               /// Returns custom name of indexer
+               /// </summary>
+               public string GetIndexerAttributeValue (EmitContext ec)
+               {
+                       if (pos_values == null) {
+                               // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
+                               // But because a lot of attribute class code must be rewritten will be better to wait...
+                               Resolve (ec);
+                       }
+                       
+                       return pos_values [0] as string;
+               }
+
+               /// <summary>
+               /// Returns condition of ConditionalAttribute
+               /// </summary>
+               public string GetConditionalAttributeValue (DeclSpace ds)
+               {
+                       if (pos_values == null) {
+                               EmitContext ec = new EmitContext (ds, ds, Location, null, null, 0, false);
+
+                               // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
+                               // But because a lot of attribute class code must be rewritten will be better to wait...
+                               Resolve (ec);
+                       }
+
+                       // Some error occurred
+                       if (pos_values [0] == null)
+                               return null;
+
+                       return (string)pos_values [0];
+               }
+
+               /// <summary>
+               /// Creates the instance of ObsoleteAttribute from this attribute instance
+               /// </summary>
+               public ObsoleteAttribute GetObsoleteAttribute (DeclSpace ds)
+               {
+                       if (pos_values == null) {
+                               EmitContext ec = new EmitContext (ds, ds, Location, null, null, 0, false);
+
+                               // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
+                               // But because a lot of attribute class code must be rewritten will be better to wait...
+                               Resolve (ec);
+                       }
+
+                       // Some error occurred
+                       if (pos_values == null)
+                               return null;
+
+                       if (pos_values.Length == 0)
+                               return new ObsoleteAttribute ();
+
+                       if (pos_values.Length == 1)
+                               return new ObsoleteAttribute ((string)pos_values [0]);
+
+                       return new ObsoleteAttribute ((string)pos_values [0], (bool)pos_values [1]);
+               }
+
+               /// <summary>
+               /// Returns value of CLSCompliantAttribute contructor parameter but because the method can be called
+               /// before ApplyAttribute. We need to resolve the arguments.
+               /// This situation occurs when class deps is differs from Emit order.  
+               /// </summary>
+               public bool GetClsCompliantAttributeValue (DeclSpace ds)
+               {
+                       if (pos_values == null) {
+                               EmitContext ec = new EmitContext (ds, ds, Location, null, null, 0, false);
+
+                               // TODO: It is not neccessary to call whole Resolve (ApplyAttribute does it now) we need only ctor args.
+                               // But because a lot of attribute class code must be rewritten will be better to wait...
+                               Resolve (ec);
+                       }
+
+                       // Some error occurred
+                       if (pos_values [0] == null)
+                               return false;
+
+                       return (bool)pos_values [0];
+               }
+
+               /// <summary>
+               /// Tests permitted SecurityAction for assembly or other types
+               /// </summary>
+               public bool CheckSecurityActionValidity (bool for_assembly)
+               {
+                       SecurityAction action  = GetSecurityActionValue ();
+
+                       if ((action == SecurityAction.RequestMinimum || action == SecurityAction.RequestOptional || action == SecurityAction.RequestRefuse) && for_assembly)
+                               return true;
+
+                       if (!for_assembly) {
+                               if (action < SecurityAction.Demand || action > SecurityAction.InheritanceDemand) {
+                                       Error_AttributeEmitError ("SecurityAction is out of range");
+                                       return false;
+                               }
+
+                               if ((action != SecurityAction.RequestMinimum && action != SecurityAction.RequestOptional && action != SecurityAction.RequestRefuse) && !for_assembly)
+                                       return true;
+                       }
+
+                       Error_AttributeEmitError (String.Concat ("SecurityAction '", action, "' is not valid for this declaration"));
+                       return false;
+               }
+
+               System.Security.Permissions.SecurityAction GetSecurityActionValue ()
+               {
+                       return (SecurityAction)pos_values [0];
+               }
+
+               /// <summary>
+               /// Creates instance of SecurityAttribute class and add result of CreatePermission method to permission table.
+               /// </summary>
+               /// <returns></returns>
+               public void ExtractSecurityPermissionSet (ListDictionary permissions)
+               {
+                       if (TypeManager.LookupDeclSpace (Type) != null && RootContext.StdLib) {
+                               Error_AttributeEmitError ("security custom attributes can not be referenced from defining assembly");
+                               return;
+                       }
+
+                       SecurityAttribute sa;
+                       // For all assemblies except corlib we can avoid all hacks
+                       if (RootContext.StdLib) {
+                               sa = (SecurityAttribute) Activator.CreateInstance (Type, pos_values);
+
+                               if (prop_info_arr != null) {
+                                       for (int i = 0; i < prop_info_arr.Length; ++i) {
+                                               PropertyInfo pi = prop_info_arr [i];
+                                               pi.SetValue (sa, prop_values_arr [i], null);
+                                       }
+                               }
+                       } else {
+                               Type temp_type = Type.GetType (Type.FullName);
+                               // HACK: All mscorlib attributes have same ctor syntax
+                               sa = (SecurityAttribute) Activator.CreateInstance (temp_type, new object[] { GetSecurityActionValue () } );
+
+                               // All types are from newly created corlib but for invocation with old we need to convert them
+                               if (prop_info_arr != null) {
+                                       for (int i = 0; i < prop_info_arr.Length; ++i) {
+                                               PropertyInfo emited_pi = prop_info_arr [i];
+                                               PropertyInfo pi = temp_type.GetProperty (emited_pi.Name, emited_pi.PropertyType);
+
+                                               object old_instance = pi.PropertyType.IsEnum ?
+                                                       System.Enum.ToObject (pi.PropertyType, prop_values_arr [i]) :
+                                                       prop_values_arr [i];
+
+                                               pi.SetValue (sa, old_instance, null);
+                                       }
+                               }
+                       }
+
+                       IPermission perm = sa.CreatePermission ();
+                       SecurityAction action;
+
+                       // IS is correct because for corlib we are using an instance from old corlib
+                       if (perm is System.Security.CodeAccessPermission) {
+                               action = GetSecurityActionValue ();
+                       } else {
+                               switch (GetSecurityActionValue ()) {
+                                       case SecurityAction.Demand:
+                                               action = (SecurityAction)13;
+                                               break;
+                                       case SecurityAction.LinkDemand:
+                                               action = (SecurityAction)14;
+                                               break;
+                                       case SecurityAction.InheritanceDemand:
+                                               action = (SecurityAction)15;
+                                               break;
+                                       default:
+                                               Error_AttributeEmitError ("Invalid SecurityAction for non-Code Access Security permission");
+                                               return;
+                               }
+                       }
+
+                       PermissionSet ps = (PermissionSet)permissions [action];
+                       if (ps == null) {
+                               ps = new PermissionSet (PermissionState.None);
+                               permissions.Add (action, ps);
+                       }
+                       ps.AddPermission (sa.CreatePermission ());
+               }
+
+               object GetValue (object value)
+               {
+                       if (value is EnumConstant)
+                               return ((EnumConstant) value).GetValue ();
+                       else
+                               return value;                           
+               }
+
+               public object GetPositionalValue (int i)
+               {
+                       return (pos_values == null) ? null : pos_values[i];
+               }
+
+               object GetFieldValue (string name)
+                {
+                       int i;
+                       if (field_info_arr == null)
+                               return null;
+                       i = 0;
+                       foreach (FieldInfo fi in field_info_arr) {
+                               if (fi.Name == name)
+                                       return GetValue (field_values_arr [i]);
+                               i++;
+                       }
+                       return null;
+               }
+
+               public UnmanagedMarshal GetMarshal (Attributable attr)
+               {
+                       object value = GetFieldValue ("SizeParamIndex");
+                       if (value != null && UnmanagedType != UnmanagedType.LPArray) {
+                               Error_AttributeEmitError ("SizeParamIndex field is not valid for the specified unmanaged type");
+                               return null;
+                       }
+
+                       object o = GetFieldValue ("ArraySubType");
+                       UnmanagedType array_sub_type = o == null ? UnmanagedType.I4 : (UnmanagedType) o;
+                       
+                       switch (UnmanagedType) {
+                       case UnmanagedType.CustomMarshaler:
+                               MethodInfo define_custom = typeof (UnmanagedMarshal).GetMethod ("DefineCustom",
+                                                                       BindingFlags.Static | BindingFlags.Public);
+                               if (define_custom == null) {
+                                       Report.RuntimeMissingSupport (Location, "set marshal info");
+                                       return null;
+                               }
+                               
+                               object [] args = new object [4];
+                               args [0] = GetFieldValue ("MarshalTypeRef");
+                               args [1] = GetFieldValue ("MarshalCookie");
+                               args [2] = GetFieldValue ("MarshalType");
+                               args [3] = Guid.Empty;
+                               return (UnmanagedMarshal) define_custom.Invoke (null, args);
+                               
+                       case UnmanagedType.LPArray:                             
+                               return UnmanagedMarshal.DefineLPArray (array_sub_type);
+                       
+                       case UnmanagedType.SafeArray:
+                               return UnmanagedMarshal.DefineSafeArray (array_sub_type);
+                       
+                       case UnmanagedType.ByValArray:
+                               FieldMember fm = attr as FieldMember;
+                               if (fm == null) {
+                                       Error_AttributeEmitError ("Specified unmanaged type is only valid on fields");
+                                       return null;
+                               }
+                               return UnmanagedMarshal.DefineByValArray ((int) GetFieldValue ("SizeConst"));
+                       
+                       case UnmanagedType.ByValTStr:
+                               return UnmanagedMarshal.DefineByValTStr ((int) GetFieldValue ("SizeConst"));
+                       
+                       default:
+                               return UnmanagedMarshal.DefineUnmanagedMarshal (UnmanagedType);
+                       }
+               }
+
+               public bool IsInternalCall
+               {
+                       get { return ImplOptions == MethodImplOptions.InternalCall; }
+               }
+
+               /// <summary>
+               /// Emit attribute for Attributable symbol
+               /// </summary>
+               public void Emit (EmitContext ec, Attributable ias, ListDictionary emitted_attr)
+               {
+                       CustomAttributeBuilder cb = Resolve (ec);
+                       if (cb == null)
+                               return;
+
+                       AttributeUsageAttribute usage_attr = GetAttributeUsage ();
+                       if ((usage_attr.ValidOn & Target) == 0) {
+                               Report.Error (592, Location, "Attribute '{0}' is not valid on this declaration type. It is valid on {1} declarations only.", Name, GetValidTargets ());
+                               return;
+                       }
+
+                       ias.ApplyAttributeBuilder (this, cb);
+
+                       if (!usage_attr.AllowMultiple) {
+                               ArrayList emitted_targets = (ArrayList)emitted_attr [Type];
+                               if (emitted_targets == null) {
+                                       emitted_targets = new ArrayList ();
+                                       emitted_attr.Add (Type, emitted_targets);
+                               } else if (emitted_targets.Contains (Target)) {
+                               Report.Error (579, Location, "Duplicate '" + Name + "' attribute");
+                                       return;
+                               }
+                               emitted_targets.Add (Target);
+                       }
+
+                       if (!RootContext.VerifyClsCompliance)
+                               return;
+
+                       // Here we are testing attribute arguments for array usage (error 3016)
+                       if (ias.IsClsCompliaceRequired (ec.DeclSpace)) {
+                               if (Arguments == null)
+                                       return;
+
+                               ArrayList pos_args = (ArrayList) Arguments [0];
+                               if (pos_args != null) {
+                                       foreach (Argument arg in pos_args) { 
+                                               // Type is undefined (was error 246)
+                                               if (arg.Type == null)
+                                                       return;
+
+                                               if (arg.Type.IsArray) {
+                                                       Report.Error (3016, Location, "Arrays as attribute arguments are not CLS-compliant");
+                                                       return;
+                                               }
+                                       }
+                               }
+                       
+                               if (Arguments.Count < 2)
+                                       return;
+                       
+                               ArrayList named_args = (ArrayList) Arguments [1];
+                               foreach (DictionaryEntry de in named_args) {
+                                       Argument arg  = (Argument) de.Value;
+
+                                       // Type is undefined (was error 246)
+                                       if (arg.Type == null)
+                                               return;
+
+                                       if (arg.Type.IsArray) {
+                                               Report.Error (3016, Location, "Arrays as attribute arguments are not CLS-compliant");
+                                               return;
+                                       }
+                               }
+                       }
+               }
+
+               public object GetValue (EmitContext ec, Constant c, Type target)
+               {
+                       if (Convert.ImplicitConversionExists (ec, c, target))
+                               return c.GetValue ();
+
+                       Convert.Error_CannotImplicitConversion (Location, c.Type, target);
+                       return null;
+               }
+               
+               public MethodBuilder DefinePInvokeMethod (EmitContext ec, TypeBuilder builder, string name,
+                                                         MethodAttributes flags, Type ret_type, Type [] param_types)
+               {
+                       //
+                       // We extract from the attribute the information we need 
+                       //
+
+                       if (Arguments == null) {
+                               Console.WriteLine ("Internal error : this is not supposed to happen !");
+                               return null;
+                       }
+
+                       ResolveType (ec);
+                       if (Type == null)
+                               return null;
+                       
+                       ArrayList named_args = new ArrayList ();
+                       
+                       ArrayList pos_args = (ArrayList) Arguments [0];
+                       if (Arguments.Count > 1)
+                               named_args = (ArrayList) Arguments [1];
+                       
+
+                       string dll_name = null;
+                       
+                       Argument tmp = (Argument) pos_args [0];
+
+                       if (!tmp.Resolve (ec, Location))
+                               return null;
+                       
+                       if (tmp.Expr is Constant)
+                               dll_name = (string) ((Constant) tmp.Expr).GetValue ();
+                       else { 
+                               Error_AttributeArgumentNotValid (Location);
+                               return null;
+                       }
+
+                       // Now we process the named arguments
+                       CallingConvention cc = CallingConvention.Winapi;
+                       CharSet charset = CharSet.Ansi;
+                       bool preserve_sig = true;
+#if FIXME
+                       bool exact_spelling = false;
+#endif
+                       bool set_last_err = false;
+                       string entry_point = null;
+
+                       for (int i = 0; i < named_args.Count; i++) {
+
+                               DictionaryEntry de = (DictionaryEntry) named_args [i];
+
+                               string member_name = (string) de.Key;
+                               Argument a  = (Argument) de.Value;
+
+                               if (!a.Resolve (ec, Location))
+                                       return null;
+
+                               Expression member = Expression.MemberLookup (
+                                       ec, Type, member_name, 
+                                       MemberTypes.Field | MemberTypes.Property,
+                                       BindingFlags.Public | BindingFlags.Instance,
+                                       Location);
+
+                               if (member == null || !(member is FieldExpr)) {
+                                       Error_InvalidNamedArgument (member_name);
+                                       return null;
+                               }
+
+                               if (member is FieldExpr) {
+                                       FieldExpr fe = (FieldExpr) member;
+                                       FieldInfo fi = fe.FieldInfo;
+
+                                       if (fi.IsInitOnly) {
+                                               Error_InvalidNamedArgument (member_name);
+                                               return null;
+                                       }
+
+                                       if (a.Expr is Constant) {
+                                               Constant c = (Constant) a.Expr;
+
+                                               try {
+                                                       if (member_name == "CallingConvention"){
+                                                               object val = GetValue (ec, c, typeof (CallingConvention));
+                                                               if (val == null)
+                                                                       return null;
+                                                               cc = (CallingConvention) val;
+                                                       } else if (member_name == "CharSet"){
+                                                               charset = (CharSet) c.GetValue ();
+                                                       } else if (member_name == "EntryPoint")
+                                                               entry_point = (string) c.GetValue ();
+                                                       else if (member_name == "SetLastError")
+                                                               set_last_err = (bool) c.GetValue ();
+#if FIXME
+                                                       else if (member_name == "ExactSpelling")
+                                                               exact_spelling = (bool) c.GetValue ();
+#endif
+                                                       else if (member_name == "PreserveSig")
+                                                               preserve_sig = (bool) c.GetValue ();
+                                               } catch (InvalidCastException){
+                                                       Error_InvalidNamedArgument (member_name);
+                                                       Error_AttributeArgumentNotValid (Location);
+                                               }
+                                       } else { 
+                                               Error_AttributeArgumentNotValid (Location);
+                                               return null;
+                                       }
+                                       
+                               }
+                       }
+
+                       if (entry_point == null)
+                               entry_point = name;
+                       if (set_last_err)
+                               charset = (CharSet)((int)charset | 0x40);
+                       
+                       MethodBuilder mb = builder.DefinePInvokeMethod (
+                               name, dll_name, entry_point, flags | MethodAttributes.HideBySig,
+                               CallingConventions.Standard,
+                               ret_type,
+                               param_types,
+                               cc,
+                               charset);
+
+                       if (preserve_sig)
+                               mb.SetImplementationFlags (MethodImplAttributes.PreserveSig);
+                       
+                       return mb;
+               }
+
+               private Expression GetValue () 
+               {
+                       if ((Arguments == null) || (Arguments.Count < 1))
+                               return null;
+                       ArrayList al = (ArrayList) Arguments [0];
+                       if ((al == null) || (al.Count < 1))
+                               return null;
+                       Argument arg = (Argument) al [0];
+                       if ((arg == null) || (arg.Expr == null))
+                               return null;
+                       return arg.Expr;
+               }
+
+               public string GetString () 
+               {
+                       Expression e = GetValue ();
+                       if (e is StringLiteral)
+                               return (e as StringLiteral).Value;
+                       return null;
+               }
+
+               public bool GetBoolean () 
+               {
+                       Expression e = GetValue ();
+                       if (e is BoolLiteral)
+                               return (e as BoolLiteral).Value;
+                       return false;
+               }
+
+               public bool IsAssemblyAttribute {
+                       get {
+                               return ExplicitTarget == "assembly";
+                       }
+               }
+       
+               public bool IsModuleAttribute {
+                       get {
+                               return ExplicitTarget == "module";
+                       }
+               }
+       }
+       
+
+       /// <summary>
+       /// For global attributes (assembly, module) we need special handling.
+       /// Attributes can be located in the several files
+       /// </summary>
+       public class GlobalAttribute: Attribute
+       {
+               public readonly NamespaceEntry ns;
+
+               public GlobalAttribute (TypeContainer container, string target, string name, ArrayList args, Location loc):
+                       base (target, name, args, loc)
+               {
+                       ns = container.NamespaceEntry;
+               }
+
+               protected override Type CheckAttributeType (EmitContext ec)
+               {
+                       // RootContext.Tree.Types has a single NamespaceEntry which gets overwritten
+                       // each time a new file is parsed.  However, we need to use the NamespaceEntry
+                       // in effect where the attribute was used.  Since code elsewhere cannot assume
+                       // that the NamespaceEntry is right, just overwrite it.
+                       //
+                       // FIXME: Check every place the NamespaceEntry of RootContext.Tree.Types is used
+                       //        to ensure the right one is used.
+                       if (ec.DeclSpace == RootContext.Tree.Types)
+                               ec.DeclSpace.NamespaceEntry = ns;
+
+                       return base.CheckAttributeType (ec);
+               }
+       }
+
+       public class Attributes {
+               public ArrayList Attrs;
+
+               public Attributes (Attribute a)
+               {
+                       Attrs = new ArrayList ();
+                       Attrs.Add (a);
+               }
+
+               public Attributes (ArrayList attrs)
+               {
+                       Attrs = attrs;
+               }
+
+               public void AddAttributes (ArrayList attrs)
+               {
+                       Attrs.AddRange (attrs);
+               }
+
+               public void AddAttribute (Attribute attr)
+               {
+                       Attrs.Add (attr);
+               }
+
+               /// <summary>
+               /// Checks whether attribute target is valid for the current element
+               /// </summary>
+               public bool CheckTargets (Attributable member)
+               {
+                       string[] valid_targets = member.ValidAttributeTargets;
+                       foreach (Attribute a in Attrs) {
+                               if (a.ExplicitTarget == null || a.ExplicitTarget == valid_targets [0]) {
+                                       a.Target = member.AttributeTargets;
+                                       continue;
+                               }
+
+                               // TODO: we can skip the first item
+                               if (((IList) valid_targets).Contains (a.ExplicitTarget)) {
+                                       switch (a.ExplicitTarget) {
+                                               case "return": a.Target = AttributeTargets.ReturnValue; continue;
+                                               case "param": a.Target = AttributeTargets.Parameter; continue;
+                                               case "field": a.Target = AttributeTargets.Field; continue;
+                                               case "method": a.Target = AttributeTargets.Method; continue;
+                                               case "property": a.Target = AttributeTargets.Property; continue;
+                                       }
+                                       throw new InternalErrorException ("Unknown explicit target: " + a.ExplicitTarget);
+                               }
+
+                               StringBuilder sb = new StringBuilder ();
+                               foreach (string s in valid_targets) {
+                                       sb.Append (s);
+                                       sb.Append (", ");
+                               }
+                               sb.Remove (sb.Length - 2, 2);
+                               Report.Error (657, a.Location, "'{0}' is not a valid attribute location for this declaration. Valid attribute locations for this declaration are '{1}'", a.ExplicitTarget, sb.ToString ());
+                               return false;
+                       }
+                       return true;
+               }
+
+               public Attribute Search (Type t, EmitContext ec)
+               {
+                       foreach (Attribute a in Attrs) {
+                               if (a.ResolveType (ec) == t)
+                                       return a;
+                       }
+                       return null;
+               }
+
+               /// <summary>
+               /// Returns all attributes of type 't'. Use it when attribute is AllowMultiple = true
+               /// </summary>
+               public Attribute[] SearchMulti (Type t, EmitContext ec)
+               {
+                       ArrayList ar = null;
+
+                       foreach (Attribute a in Attrs) {
+                               if (a.ResolveType (ec) == t) {
+                                       if (ar == null)
+                                               ar = new ArrayList ();
+                                       ar.Add (a);
+                               }
+                       }
+
+                       return ar == null ? null : ar.ToArray (typeof (Attribute)) as Attribute[];
+               }
+
+               public void Emit (EmitContext ec, Attributable ias)
+               {
+                       if (!CheckTargets (ias))
+                               return;
+
+                       ListDictionary ld = new ListDictionary ();
+
+                       foreach (Attribute a in Attrs)
+                               a.Emit (ec, ias, ld);
+               }
+
+               public bool Contains (Type t, EmitContext ec)
+               {
+                        return Search (t, ec) != null;
+               }
+       }
+
+       /// <summary>
+       /// Helper class for attribute verification routine.
+       /// </summary>
+       sealed class AttributeTester
+       {
+               static PtrHashtable analyzed_types = new PtrHashtable ();
+               static PtrHashtable analyzed_types_obsolete = new PtrHashtable ();
+               static PtrHashtable analyzed_member_obsolete = new PtrHashtable ();
+               static PtrHashtable analyzed_method_excluded = new PtrHashtable ();
+
+               private AttributeTester ()
+               {
+               }
+
+               /// <summary>
+               /// Returns true if parameters of two compared methods are CLS-Compliant.
+               /// It tests differing only in ref or out, or in array rank.
+               /// </summary>
+               public static bool AreOverloadedMethodParamsClsCompliant (Type[] types_a, Type[] types_b) 
+               {
+                       if (types_a == null || types_b == null)
+                               return true;
+
+                       if (types_a.Length != types_b.Length)
+                               return true;
+
+                       for (int i = 0; i < types_b.Length; ++i) {
+                               Type aType = types_a [i];
+                               Type bType = types_b [i];
+
+                               if (aType.IsArray && bType.IsArray && aType.GetArrayRank () != bType.GetArrayRank () && aType.GetElementType () == bType.GetElementType ()) {
+                                       return false;
+                               }
+
+                               Type aBaseType = aType;
+                               bool is_either_ref_or_out = false;
+
+                               if (aType.IsByRef || aType.IsPointer) {
+                                       aBaseType = aType.GetElementType ();
+                                       is_either_ref_or_out = true;
+                               }
+
+                               Type bBaseType = bType;
+                               if (bType.IsByRef || bType.IsPointer) 
+                               {
+                                       bBaseType = bType.GetElementType ();
+                                       is_either_ref_or_out = !is_either_ref_or_out;
+                               }
+
+                               if (aBaseType != bBaseType)
+                                       continue;
+
+                               if (is_either_ref_or_out)
+                                       return false;
+                       }
+                       return true;
+               }
+
+               /// <summary>
+               /// Goes through all parameters and test if they are CLS-Compliant.
+               /// </summary>
+               public static bool AreParametersCompliant (Parameter[] fixedParameters, Location loc)
+               {
+                       if (fixedParameters == null)
+                               return true;
+
+                       foreach (Parameter arg in fixedParameters) {
+                               if (!AttributeTester.IsClsCompliant (arg.ParameterType)) {
+                                       Report.Error (3001, loc, "Argument type '{0}' is not CLS-compliant", arg.GetSignatureForError ());
+                                       return false;
+                               }
+                       }
+                       return true;
+               }
+
+
+               /// <summary>
+               /// This method tests the CLS compliance of external types. It doesn't test type visibility.
+               /// </summary>
+               public static bool IsClsCompliant (Type type) 
+               {
+                       if (type == null)
+                               return true;
+
+                       object type_compliance = analyzed_types[type];
+                       if (type_compliance != null)
+                               return type_compliance == TRUE;
+
+                       if (type.IsPointer) {
+                               analyzed_types.Add (type, null);
+                               return false;
+                       }
+
+                       bool result;
+                       if (type.IsArray || type.IsByRef)       {
+                               result = IsClsCompliant (TypeManager.GetElementType (type));
+                       } else {
+                               result = AnalyzeTypeCompliance (type);
+                       }
+                       analyzed_types.Add (type, result ? TRUE : FALSE);
+                       return result;
+               }                
+
+               static object TRUE = new object ();
+               static object FALSE = new object ();
+
+               public static void VerifyModulesClsCompliance ()
+               {
+                       Module[] modules = TypeManager.Modules;
+                       if (modules == null)
+                               return;
+
+                       // The first module is generated assembly
+                       for (int i = 1; i < modules.Length; ++i) {
+                               Module module = modules [i];
+                               if (!IsClsCompliant (module)) {
+                                       Report.Error (3013, "Added modules must be marked with the CLSCompliant attribute to match the assembly", module.Name);
+                                       return;
+                               }
+                       }
+               }
+
+               /// <summary>
+               /// Tests container name for CLS-Compliant name (differing only in case)
+               /// </summary>
+               public static void VerifyTopLevelNameClsCompliance ()
+               {
+                       Hashtable locase_table = new Hashtable ();
+
+                       // Convert imported type names to lower case and ignore not cls compliant
+                       foreach (DictionaryEntry de in TypeManager.all_imported_types) {
+                               Type t = (Type)de.Value;
+                               if (!AttributeTester.IsClsCompliant (t))
+                                       continue;
+
+                               locase_table.Add (((string)de.Key).ToLower (System.Globalization.CultureInfo.InvariantCulture), t);
+                       }
+
+                       foreach (DictionaryEntry de in RootContext.Tree.Decls) {
+                               DeclSpace decl = (DeclSpace)de.Value;
+                               if (!decl.IsClsCompliaceRequired (decl))
+                                       continue;
+
+                               string lcase = decl.Name.ToLower (System.Globalization.CultureInfo.InvariantCulture);
+                               if (!locase_table.Contains (lcase)) {
+                                       locase_table.Add (lcase, decl);
+                                       continue;
+                               }
+
+                               object conflict = locase_table [lcase];
+                               if (conflict is Type)
+                                       Report.SymbolRelatedToPreviousError ((Type)conflict);
+                               else
+                                       Report.SymbolRelatedToPreviousError ((MemberCore)conflict);
+
+                               Report.Error (3005, decl.Location, "Identifier '{0}' differing only in case is not CLS-compliant", decl.GetSignatureForError ());
+                       }
+               }
+
+               static bool IsClsCompliant (ICustomAttributeProvider attribute_provider) 
+               {
+                       object[] CompliantAttribute = attribute_provider.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
+                       if (CompliantAttribute.Length == 0)
+                               return false;
+
+                       return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant;
+               }
+
+               static bool AnalyzeTypeCompliance (Type type)
+               {
+                       DeclSpace ds = TypeManager.LookupDeclSpace (type);
+                       if (ds != null) {
+                               return ds.IsClsCompliaceRequired (ds.Parent);
+                       }
+
+                       if (type.IsGenericParameter || type.IsGenericInstance)
+                               return false;
+
+                       object[] CompliantAttribute = type.GetCustomAttributes (TypeManager.cls_compliant_attribute_type, false);
+                       if (CompliantAttribute.Length == 0) 
+                               return IsClsCompliant (type.Assembly);
+
+                       return ((CLSCompliantAttribute)CompliantAttribute[0]).IsCompliant;
+               }
+
+               /// <summary>
+               /// Returns instance of ObsoleteAttribute when type is obsolete
+               /// </summary>
+               public static ObsoleteAttribute GetObsoleteAttribute (Type type)
+               {
+                       object type_obsolete = analyzed_types_obsolete [type];
+                       if (type_obsolete == FALSE)
+                               return null;
+
+                       if (type_obsolete != null)
+                               return (ObsoleteAttribute)type_obsolete;
+
+                       ObsoleteAttribute result = null;
+                       if (type.IsByRef || type.IsArray || type.IsPointer) {
+                               result = GetObsoleteAttribute (TypeManager.GetElementType (type));
+                       } else if (type.IsGenericParameter || type.IsGenericInstance)
+                               return null;
+                       else {
+                               DeclSpace type_ds = TypeManager.LookupDeclSpace (type);
+
+                               // Type is external, we can get attribute directly
+                               if (type_ds == null) {
+                                       object[] attribute = type.GetCustomAttributes (TypeManager.obsolete_attribute_type, false);
+                                       if (attribute.Length == 1)
+                                               result = (ObsoleteAttribute)attribute [0];
+                               } else {
+                                       result = type_ds.GetObsoleteAttribute (type_ds);
+                               }
+                       }
+
+                       analyzed_types_obsolete.Add (type, result == null ? FALSE : result);
+                       return result;
+               }
+
+               /// <summary>
+               /// Returns instance of ObsoleteAttribute when method is obsolete
+               /// </summary>
+               public static ObsoleteAttribute GetMethodObsoleteAttribute (MethodBase mb)
+               {
+                       IMethodData mc = TypeManager.GetMethod (mb);
+                       if (mc != null) 
+                               return mc.GetObsoleteAttribute ();
+
+                       // compiler generated methods are not registered by AddMethod
+                       if (mb.DeclaringType is TypeBuilder)
+                               return null;
+
+                       return GetMemberObsoleteAttribute (mb);
+               }
+
+               /// <summary>
+               /// Returns instance of ObsoleteAttribute when member is obsolete
+               /// </summary>
+               public static ObsoleteAttribute GetMemberObsoleteAttribute (MemberInfo mi)
+               {
+                       object type_obsolete = analyzed_member_obsolete [mi];
+                       if (type_obsolete == FALSE)
+                               return null;
+
+                       if (type_obsolete != null)
+                               return (ObsoleteAttribute)type_obsolete;
+
+                       if ((mi.DeclaringType is TypeBuilder) || mi.DeclaringType.IsGenericInstance)
+                               return null;
+
+                       ObsoleteAttribute oa = System.Attribute.GetCustomAttribute (mi, TypeManager.obsolete_attribute_type, false) as ObsoleteAttribute;
+                       analyzed_member_obsolete.Add (mi, oa == null ? FALSE : oa);
+                       return oa;
+               }
+
+               /// <summary>
+               /// Common method for Obsolete error/warning reporting.
+               /// </summary>
+               public static void Report_ObsoleteMessage (ObsoleteAttribute oa, string member, Location loc)
+               {
+                       if (oa.IsError) {
+                               Report.Error (619, loc, "'{0}' is obsolete: '{1}'", member, oa.Message);
+                               return;
+                       }
+
+                       if (oa.Message == null) {
+                               Report.Warning (612, loc, "'{0}' is obsolete", member);
+                               return;
+                       }
+                       if (RootContext.WarningLevel >= 2)
+                               Report.Warning (618, loc, "'{0}' is obsolete: '{1}'", member, oa.Message);
+               }
+
+               public static bool IsConditionalMethodExcluded (MethodBase mb)
+               {
+                       object excluded = analyzed_method_excluded [mb];
+                       if (excluded != null)
+                               return excluded == TRUE ? true : false;
+
+                       if (mb.Mono_IsInflatedMethod)
+                               return false;
+                       
+                       ConditionalAttribute[] attrs = mb.GetCustomAttributes (TypeManager.conditional_attribute_type, true) as ConditionalAttribute[];
+                       if (attrs.Length == 0) {
+                               analyzed_method_excluded.Add (mb, FALSE);
+                               return false;
+                       }
+
+                       foreach (ConditionalAttribute a in attrs) {
+                               if (RootContext.AllDefines.Contains (a.ConditionString)) {
+                                       analyzed_method_excluded.Add (mb, FALSE);
+                                       return false;
+                               }
+                       }
+                       analyzed_method_excluded.Add (mb, TRUE);
+                       return true;
+               }
+       }
+}
diff --git a/mcs/bmcs/bmcs.exe.config b/mcs/bmcs/bmcs.exe.config
new file mode 100644 (file)
index 0000000..16ccafe
--- /dev/null
@@ -0,0 +1,14 @@
+<configuration>\r
+       <startup>\r
+               <supportedRuntime version="v2.0.40607"/>\r
+       </startup>\r
+  <system.diagnostics>\r
+    <trace autoflush="true" indentsize="4">\r
+      <listeners>\r
+        <add name="compilerLogListener" type="System.Diagnostics.TextWriterTraceListener,System"\r
+             initializeData="mcs.log" />\r
+        <remove type="System.Diagnostics.DefaultTraceListener,System"/>\r
+      </listeners>\r
+    </trace>\r
+  </system.diagnostics>\r
+</configuration>\r
diff --git a/mcs/bmcs/bmcs.exe.sources b/mcs/bmcs/bmcs.exe.sources
new file mode 100644 (file)
index 0000000..f457890
--- /dev/null
@@ -0,0 +1,39 @@
+AssemblyInfo.cs
+anonymous.cs
+assign.cs
+attribute.cs
+driver.cs
+mb-tokenizer.cs
+cfold.cs
+class.cs
+codegen.cs
+const.cs
+constant.cs
+convert.cs
+decl.cs
+delegate.cs
+doc.cs
+enum.cs
+ecore.cs
+expression.cs
+flowanalysis.cs
+generic.cs
+iterators.cs
+literal.cs
+location.cs
+modifiers.cs
+namespace.cs
+parameter.cs
+pending.cs
+report.cs
+rootcontext.cs
+statement.cs
+support.cs
+typemanager.cs
+symbolwriter.cs
+tree.cs
+module.cs
+../class/corlib/Mono.Security.Cryptography/CryptoConvert.cs
+../class/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs
+../class/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs
+../class/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs
diff --git a/mcs/bmcs/cfold.cs b/mcs/bmcs/cfold.cs
new file mode 100644 (file)
index 0000000..9465eaa
--- /dev/null
@@ -0,0 +1,1246 @@
+//
+// cfold.cs: Constant Folding
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2002, 2003 Ximian, Inc.
+//
+
+using System;
+
+namespace Mono.CSharp {
+
+       public class ConstantFold {
+
+               //
+               // Performs the numeric promotions on the left and right expresions
+               // and desposits the results on `lc' and `rc'.
+               //
+               // On success, the types of `lc' and `rc' on output will always match,
+               // and the pair will be one of:
+               //
+               //   (double, double)
+               //   (float, float)
+               //   (ulong, ulong)
+               //   (long, long)
+               //   (uint, uint)
+               //   (int, int)
+               //   (short, short)   (Happens with enumerations with underlying short type)
+               //   (ushort, ushort) (Happens with enumerations with underlying short type)
+               //
+               static void DoConstantNumericPromotions (EmitContext ec, Binary.Operator oper,
+                                                        ref Constant left, ref Constant right,
+                                                        Location loc)
+               {
+                       if (left is DoubleConstant || right is DoubleConstant){
+                               //
+                               // If either side is a double, convert the other to a double
+                               //
+                               if (!(left is DoubleConstant))
+                                       left = left.ToDouble (loc);
+
+                               if (!(right is DoubleConstant))
+                                       right = right.ToDouble (loc);
+                               return;
+                       } else if (left is FloatConstant || right is FloatConstant) {
+                               //
+                               // If either side is a float, convert the other to a float
+                               //
+                               if (!(left is FloatConstant))
+                                       left = left.ToFloat (loc);
+
+                               if (!(right is FloatConstant))
+                                       right = right.ToFloat (loc);
+;                              return;
+                       } else if (left is ULongConstant || right is ULongConstant){
+                               //
+                               // If either operand is of type ulong, the other operand is
+                               // converted to type ulong.  or an error ocurrs if the other
+                               // operand is of type sbyte, short, int or long
+                               //
+#if WRONG
+                               Constant match, other;
+#endif
+                                       
+                               if (left is ULongConstant){
+#if WRONG
+                                       other = right;
+                                       match = left;
+#endif
+                                       if (!(right is ULongConstant))
+                                               right = right.ToULong (loc);
+                               } else {
+#if WRONG
+                                       other = left;
+                                       match = right;
+#endif
+                                       left = left.ToULong (loc);
+                               }
+
+#if WRONG
+                               if (other is SByteConstant || other is ShortConstant ||
+                                   other is IntConstant || other is LongConstant){
+                                       Binary.Error_OperatorAmbiguous
+                                               (loc, oper, other.Type, match.Type);
+                                       left = null;
+                                       right = null;
+                               }
+#endif
+                               return;
+                       } else if (left is LongConstant || right is LongConstant){
+                               //
+                               // If either operand is of type long, the other operand is converted
+                               // to type long.
+                               //
+                               if (!(left is LongConstant))
+                                       left = left.ToLong (loc);
+                               else if (!(right is LongConstant))
+                                       right = right.ToLong (loc);
+                               return;
+                       } else if (left is UIntConstant || right is UIntConstant){
+                               //
+                               // If either operand is of type uint, and the other
+                               // operand is of type sbyte, short or int, the operands are
+                               // converted to type long.
+                               //
+                               Constant other;
+                               if (left is UIntConstant)
+                                       other = right;
+                               else
+                                       other = left;
+
+                               // Nothing to do.
+                               if (other is UIntConstant)
+                                       return;
+
+                               IntConstant ic = other as IntConstant;
+                               if (ic != null){
+                                       if (ic.Value >= 0){
+                                               if (left == other)
+                                                       left = new UIntConstant ((uint) ic.Value);
+                                               else
+                                                       right = new UIntConstant ((uint) ic.Value);
+                                               return;
+                                       }
+                               }
+                               
+                               if (other is SByteConstant || other is ShortConstant || ic != null){
+                                       left = left.ToLong (loc);
+                                       right = right.ToLong (loc);
+                               } else {
+                                       left = left.ToUInt (loc);
+                                       right = left.ToUInt (loc);
+                               }
+
+                               return;
+                       } else if (left is DecimalConstant || right is DecimalConstant) {
+                               if (!(left is DecimalConstant))
+                                       left = left.ToDecimal (loc);
+                               else if (!(right is DecimalConstant))
+                                       right = right.ToDecimal (loc);
+                               return;
+                       } else if (left is EnumConstant || right is EnumConstant){
+                               //
+                               // If either operand is an enum constant, the other one must
+                               // be implicitly convertable to that enum's underlying type.
+                               //
+                               EnumConstant match;
+                               Constant other;
+                               if (left is EnumConstant){
+                                       other = right;
+                                       match = (EnumConstant) left;
+                               } else {
+                                       other = left;
+                                       match = (EnumConstant) right;
+                               }
+
+                               bool need_check = (other is EnumConstant) ||
+                                       ((oper != Binary.Operator.Addition) &&
+                                        (oper != Binary.Operator.Subtraction));
+
+                               if (need_check &&
+                                   !Convert.ImplicitConversionExists (ec, match, other.Type)) {
+                                       Convert.Error_CannotImplicitConversion (loc, match.Type, other.Type);
+                                       left = null;
+                                       right = null;
+                                       return;
+                               }
+
+                               if (left is EnumConstant)
+                                       left = ((EnumConstant) left).Child;
+                               if (right is EnumConstant)
+                                       right = ((EnumConstant) right).Child;
+
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               return;
+
+                       } else {
+                               //
+                               // Force conversions to int32
+                               //
+                               if (!(left is IntConstant))
+                                       left = left.ToInt (loc);
+                               if (!(right is IntConstant))
+                                       right = right.ToInt (loc);
+                       }
+                       return;
+               }
+
+               static void Error_CompileTimeOverflow (Location loc)
+               {
+                       Report.Error (220, loc, "The operation overflows at compile time in checked mode");
+               }
+               
+               /// <summary>
+               ///   Constant expression folder for binary operations.
+               ///
+               ///   Returns null if the expression can not be folded.
+               /// </summary>
+               static public Expression BinaryFold (EmitContext ec, Binary.Operator oper,
+                                                    Constant left, Constant right, Location loc)
+               {
+                       Type lt = left.Type;
+                       Type rt = right.Type;
+                       Type result_type = null;
+                       bool bool_res;
+
+                       //
+                       // Enumerator folding
+                       //
+                       if (rt == lt && left is EnumConstant)
+                               result_type = lt;
+
+                       //
+                       // During an enum evaluation, we need to unwrap enumerations
+                       //
+                       if (ec.InEnumContext){
+                               if (left is EnumConstant)
+                                       left = ((EnumConstant) left).Child;
+                               
+                               if (right is EnumConstant)
+                                       right = ((EnumConstant) right).Child;
+                       }
+
+                       Type wrap_as;
+                       Constant result = null;
+                       switch (oper){
+                       case Binary.Operator.BitwiseOr:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               if (left is IntConstant){
+                                       IntConstant v;
+                                       int res = ((IntConstant) left).Value | ((IntConstant) right).Value;
+                                       
+                                       v = new IntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is UIntConstant){
+                                       UIntConstant v;
+                                       uint res = ((UIntConstant)left).Value | ((UIntConstant)right).Value;
+                                       
+                                       v = new UIntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is LongConstant){
+                                       LongConstant v;
+                                       long res = ((LongConstant)left).Value | ((LongConstant)right).Value;
+                                       
+                                       v = new LongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is ULongConstant){
+                                       ULongConstant v;
+                                       ulong res = ((ULongConstant)left).Value |
+                                               ((ULongConstant)right).Value;
+                                       
+                                       v = new ULongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is UShortConstant){
+                                       UShortConstant v;
+                                       ushort res = (ushort) (((UShortConstant)left).Value |
+                                                              ((UShortConstant)right).Value);
+                                       
+                                       v = new UShortConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is ShortConstant){
+                                       ShortConstant v;
+                                       short res = (short) (((ShortConstant)left).Value |
+                                                            ((ShortConstant)right).Value);
+                                       
+                                       v = new ShortConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               }
+                               break;
+                               
+                       case Binary.Operator.BitwiseAnd:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+                               
+                               if (left is IntConstant){
+                                       IntConstant v;
+                                       int res = ((IntConstant) left).Value & ((IntConstant) right).Value;
+                                       
+                                       v = new IntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is UIntConstant){
+                                       UIntConstant v;
+                                       uint res = ((UIntConstant)left).Value & ((UIntConstant)right).Value;
+                                       
+                                       v = new UIntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is LongConstant){
+                                       LongConstant v;
+                                       long res = ((LongConstant)left).Value & ((LongConstant)right).Value;
+                                       
+                                       v = new LongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is ULongConstant){
+                                       ULongConstant v;
+                                       ulong res = ((ULongConstant)left).Value &
+                                               ((ULongConstant)right).Value;
+                                       
+                                       v = new ULongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is UShortConstant){
+                                       UShortConstant v;
+                                       ushort res = (ushort) (((UShortConstant)left).Value &
+                                                              ((UShortConstant)right).Value);
+                                       
+                                       v = new UShortConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is ShortConstant){
+                                       ShortConstant v;
+                                       short res = (short) (((ShortConstant)left).Value &
+                                                            ((ShortConstant)right).Value);
+                                       
+                                       v = new ShortConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               }
+                               break;
+
+                       case Binary.Operator.ExclusiveOr:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+                               
+                               if (left is IntConstant){
+                                       IntConstant v;
+                                       int res = ((IntConstant) left).Value ^ ((IntConstant) right).Value;
+                                       
+                                       v = new IntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is UIntConstant){
+                                       UIntConstant v;
+                                       uint res = ((UIntConstant)left).Value ^ ((UIntConstant)right).Value;
+                                       
+                                       v = new UIntConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is LongConstant){
+                                       LongConstant v;
+                                       long res = ((LongConstant)left).Value ^ ((LongConstant)right).Value;
+                                       
+                                       v = new LongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is ULongConstant){
+                                       ULongConstant v;
+                                       ulong res = ((ULongConstant)left).Value ^
+                                               ((ULongConstant)right).Value;
+                                       
+                                       v = new ULongConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is UShortConstant){
+                                       UShortConstant v;
+                                       ushort res = (ushort) (((UShortConstant)left).Value ^
+                                                              ((UShortConstant)right).Value);
+                                       
+                                       v = new UShortConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               } else if (left is ShortConstant){
+                                       ShortConstant v;
+                                       short res = (short)(((ShortConstant)left).Value ^
+                                                           ((ShortConstant)right).Value);
+                                       
+                                       v = new ShortConstant (res);
+                                       if (result_type == null)
+                                               return v;
+                                       else
+                                               return new EnumConstant (v, result_type);
+                               }
+                               break;
+
+                       case Binary.Operator.Addition:
+                               bool left_is_string = left is StringConstant;
+                               bool right_is_string = right is StringConstant;
+
+                               //
+                               // If both sides are strings, then concatenate, if
+                               // one is a string, and the other is not, then defer
+                               // to runtime concatenation
+                               //
+                               wrap_as = null;
+                               if (left_is_string || right_is_string){
+                                       if (left_is_string && right_is_string)
+                                               return new StringConstant (
+                                                       ((StringConstant) left).Value +
+                                                       ((StringConstant) right).Value);
+                                       
+                                       return null;
+                               }
+
+                               //
+                               // handle "E operator + (E x, U y)"
+                               // handle "E operator + (Y y, E x)"
+                               //
+                               // note that E operator + (E x, E y) is invalid
+                               //
+                               if (left is EnumConstant){
+                                       if (right is EnumConstant){
+                                               return null;
+                                       }
+                                       if (((EnumConstant) left).Child.Type != right.Type)
+                                               return null;
+
+                                       wrap_as = left.Type;
+                               } else if (right is EnumConstant){
+                                       if (((EnumConstant) right).Child.Type != left.Type)
+                                               return null;
+                                       wrap_as = right.Type;
+                               }
+
+                               result = null;
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               try {
+                                       if (left is DoubleConstant){
+                                               double res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DoubleConstant) left).Value +
+                                                                      ((DoubleConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DoubleConstant) left).Value +
+                                                                        ((DoubleConstant) right).Value);
+                                               
+                                               result = new DoubleConstant (res);
+                                       } else if (left is FloatConstant){
+                                               float res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((FloatConstant) left).Value +
+                                                                      ((FloatConstant) right).Value);
+                                               else
+                                                       res = unchecked (((FloatConstant) left).Value +
+                                                                        ((FloatConstant) right).Value);
+                                               
+                                               result = new FloatConstant (res);
+                                       } else if (left is ULongConstant){
+                                               ulong res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((ULongConstant) left).Value +
+                                                                      ((ULongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((ULongConstant) left).Value +
+                                                                        ((ULongConstant) right).Value);
+
+                                               result = new ULongConstant (res);
+                                       } else if (left is LongConstant){
+                                               long res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((LongConstant) left).Value +
+                                                                      ((LongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((LongConstant) left).Value +
+                                                                        ((LongConstant) right).Value);
+                                               
+                                               result = new LongConstant (res);
+                                       } else if (left is UIntConstant){
+                                               uint res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((UIntConstant) left).Value +
+                                                                      ((UIntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((UIntConstant) left).Value +
+                                                                        ((UIntConstant) right).Value);
+                                               
+                                               result = new UIntConstant (res);
+                                       } else if (left is IntConstant){
+                                               int res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((IntConstant) left).Value +
+                                                                      ((IntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((IntConstant) left).Value +
+                                                                        ((IntConstant) right).Value);
+
+                                               result = new IntConstant (res);
+                                       } else if (left is DecimalConstant) {
+                                               decimal res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DecimalConstant) left).Value +
+                                                               ((DecimalConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DecimalConstant) left).Value +
+                                                               ((DecimalConstant) right).Value);
+
+                                               result = new DecimalConstant (res);
+                                       } else {
+                                               throw new Exception ( "Unexepected addition input: " + left);
+                                       }
+                               } catch (OverflowException){
+                                       Error_CompileTimeOverflow (loc);
+                               }
+
+                               if (wrap_as != null)
+                                       return new EnumConstant (result, wrap_as);
+                               else
+                                       return result;
+
+                       case Binary.Operator.Subtraction:
+                               //
+                               // handle "E operator - (E x, U y)"
+                               // handle "E operator - (Y y, E x)"
+                               // handle "U operator - (E x, E y)"
+                               //
+                               wrap_as = null;
+                               if (left is EnumConstant){
+                                       if (right is EnumConstant){
+                                               if (left.Type == right.Type)
+                                                       wrap_as = TypeManager.EnumToUnderlying (left.Type);
+                                               else
+                                                       return null;
+                                       }
+                                       if (((EnumConstant) left).Child.Type != right.Type)
+                                               return null;
+
+                                       wrap_as = left.Type;
+                               } else if (right is EnumConstant){
+                                       if (((EnumConstant) right).Child.Type != left.Type)
+                                               return null;
+                                       wrap_as = right.Type;
+                               }
+
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               try {
+                                       if (left is DoubleConstant){
+                                               double res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DoubleConstant) left).Value -
+                                                                      ((DoubleConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DoubleConstant) left).Value -
+                                                                        ((DoubleConstant) right).Value);
+                                               
+                                               result = new DoubleConstant (res);
+                                       } else if (left is FloatConstant){
+                                               float res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((FloatConstant) left).Value -
+                                                                      ((FloatConstant) right).Value);
+                                               else
+                                                       res = unchecked (((FloatConstant) left).Value -
+                                                                        ((FloatConstant) right).Value);
+                                               
+                                               result = new FloatConstant (res);
+                                       } else if (left is ULongConstant){
+                                               ulong res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((ULongConstant) left).Value -
+                                                                      ((ULongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((ULongConstant) left).Value -
+                                                                        ((ULongConstant) right).Value);
+                                               
+                                               result = new ULongConstant (res);
+                                       } else if (left is LongConstant){
+                                               long res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((LongConstant) left).Value -
+                                                                      ((LongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((LongConstant) left).Value -
+                                                                        ((LongConstant) right).Value);
+                                               
+                                               result = new LongConstant (res);
+                                       } else if (left is UIntConstant){
+                                               uint res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((UIntConstant) left).Value -
+                                                                      ((UIntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((UIntConstant) left).Value -
+                                                                        ((UIntConstant) right).Value);
+                                               
+                                               result = new UIntConstant (res);
+                                       } else if (left is IntConstant){
+                                               int res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((IntConstant) left).Value -
+                                                                      ((IntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((IntConstant) left).Value -
+                                                                        ((IntConstant) right).Value);
+
+                                               result = new IntConstant (res);
+                                       } else if (left is DecimalConstant) {
+                                               decimal res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DecimalConstant) left).Value -
+                                                               ((DecimalConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DecimalConstant) left).Value -
+                                                               ((DecimalConstant) right).Value);
+
+                                               return new DecimalConstant (res);
+                                       } else {
+                                               throw new Exception ( "Unexepected subtraction input: " + left);
+                                       }
+                               } catch (OverflowException){
+                                       Error_CompileTimeOverflow (loc);
+                               }
+                               if (wrap_as != null)
+                                       return new EnumConstant (result, wrap_as);
+                               else
+                                       return result;
+                               
+                       case Binary.Operator.Multiply:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               try {
+                                       if (left is DoubleConstant){
+                                               double res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DoubleConstant) left).Value *
+                                                               ((DoubleConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DoubleConstant) left).Value *
+                                                               ((DoubleConstant) right).Value);
+                                               
+                                               return new DoubleConstant (res);
+                                       } else if (left is FloatConstant){
+                                               float res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((FloatConstant) left).Value *
+                                                               ((FloatConstant) right).Value);
+                                               else
+                                                       res = unchecked (((FloatConstant) left).Value *
+                                                               ((FloatConstant) right).Value);
+                                               
+                                               return new FloatConstant (res);
+                                       } else if (left is ULongConstant){
+                                               ulong res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((ULongConstant) left).Value *
+                                                               ((ULongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((ULongConstant) left).Value *
+                                                               ((ULongConstant) right).Value);
+                                               
+                                               return new ULongConstant (res);
+                                       } else if (left is LongConstant){
+                                               long res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((LongConstant) left).Value *
+                                                               ((LongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((LongConstant) left).Value *
+                                                               ((LongConstant) right).Value);
+                                               
+                                               return new LongConstant (res);
+                                       } else if (left is UIntConstant){
+                                               uint res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((UIntConstant) left).Value *
+                                                               ((UIntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((UIntConstant) left).Value *
+                                                               ((UIntConstant) right).Value);
+                                               
+                                               return new UIntConstant (res);
+                                       } else if (left is IntConstant){
+                                               int res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((IntConstant) left).Value *
+                                                               ((IntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((IntConstant) left).Value *
+                                                               ((IntConstant) right).Value);
+
+                                               return new IntConstant (res);
+                                       } else if (left is DecimalConstant) {
+                                               decimal res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DecimalConstant) left).Value *
+                                                               ((DecimalConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DecimalConstant) left).Value *
+                                                               ((DecimalConstant) right).Value);
+
+                                               return new DecimalConstant (res);
+                                       } else {
+                                               throw new Exception ( "Unexepected multiply input: " + left);
+                                       }
+                               } catch (OverflowException){
+                                       Error_CompileTimeOverflow (loc);
+                               }
+                               break;
+
+                       case Binary.Operator.Division:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               try {
+                                       if (left is DoubleConstant){
+                                               double res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DoubleConstant) left).Value /
+                                                               ((DoubleConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DoubleConstant) left).Value /
+                                                               ((DoubleConstant) right).Value);
+                                               
+                                               return new DoubleConstant (res);
+                                       } else if (left is FloatConstant){
+                                               float res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((FloatConstant) left).Value /
+                                                               ((FloatConstant) right).Value);
+                                               else
+                                                       res = unchecked (((FloatConstant) left).Value /
+                                                               ((FloatConstant) right).Value);
+                                               
+                                               return new FloatConstant (res);
+                                       } else if (left is ULongConstant){
+                                               ulong res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((ULongConstant) left).Value /
+                                                               ((ULongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((ULongConstant) left).Value /
+                                                               ((ULongConstant) right).Value);
+                                               
+                                               return new ULongConstant (res);
+                                       } else if (left is LongConstant){
+                                               long res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((LongConstant) left).Value /
+                                                               ((LongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((LongConstant) left).Value /
+                                                               ((LongConstant) right).Value);
+                                               
+                                               return new LongConstant (res);
+                                       } else if (left is UIntConstant){
+                                               uint res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((UIntConstant) left).Value /
+                                                               ((UIntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((UIntConstant) left).Value /
+                                                               ((UIntConstant) right).Value);
+                                               
+                                               return new UIntConstant (res);
+                                       } else if (left is IntConstant){
+                                               int res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((IntConstant) left).Value /
+                                                               ((IntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((IntConstant) left).Value /
+                                                               ((IntConstant) right).Value);
+
+                                               return new IntConstant (res);
+                                       } else if (left is DecimalConstant) {
+                                               decimal res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DecimalConstant) left).Value /
+                                                               ((DecimalConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DecimalConstant) left).Value /
+                                                               ((DecimalConstant) right).Value);
+
+                                               return new DecimalConstant (res);
+                                       } else {
+                                               throw new Exception ( "Unexepected division input: " + left);
+                                       }
+                               } catch (OverflowException){
+                                       Error_CompileTimeOverflow (loc);
+
+                               } catch (DivideByZeroException) {
+                                       Report.Error (020, loc, "Division by constant zero");
+                               }
+                               
+                               break;
+                               
+                       case Binary.Operator.Modulus:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               try {
+                                       if (left is DoubleConstant){
+                                               double res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((DoubleConstant) left).Value %
+                                                                      ((DoubleConstant) right).Value);
+                                               else
+                                                       res = unchecked (((DoubleConstant) left).Value %
+                                                                        ((DoubleConstant) right).Value);
+                                               
+                                               return new DoubleConstant (res);
+                                       } else if (left is FloatConstant){
+                                               float res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((FloatConstant) left).Value %
+                                                                      ((FloatConstant) right).Value);
+                                               else
+                                                       res = unchecked (((FloatConstant) left).Value %
+                                                                        ((FloatConstant) right).Value);
+                                               
+                                               return new FloatConstant (res);
+                                       } else if (left is ULongConstant){
+                                               ulong res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((ULongConstant) left).Value %
+                                                                      ((ULongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((ULongConstant) left).Value %
+                                                                        ((ULongConstant) right).Value);
+                                               
+                                               return new ULongConstant (res);
+                                       } else if (left is LongConstant){
+                                               long res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((LongConstant) left).Value %
+                                                                      ((LongConstant) right).Value);
+                                               else
+                                                       res = unchecked (((LongConstant) left).Value %
+                                                                        ((LongConstant) right).Value);
+                                               
+                                               return new LongConstant (res);
+                                       } else if (left is UIntConstant){
+                                               uint res;
+                                               
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((UIntConstant) left).Value %
+                                                                      ((UIntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((UIntConstant) left).Value %
+                                                                        ((UIntConstant) right).Value);
+                                               
+                                               return new UIntConstant (res);
+                                       } else if (left is IntConstant){
+                                               int res;
+
+                                               if (ec.ConstantCheckState)
+                                                       res = checked (((IntConstant) left).Value %
+                                                                      ((IntConstant) right).Value);
+                                               else
+                                                       res = unchecked (((IntConstant) left).Value %
+                                                                        ((IntConstant) right).Value);
+
+                                               return new IntConstant (res);
+                                       } else {
+                                               throw new Exception ( "Unexepected modulus input: " + left);
+                                       }
+                               } catch (DivideByZeroException){
+                                       Report.Error (020, loc, "Division by constant zero");
+                               } catch (OverflowException){
+                                       Error_CompileTimeOverflow (loc);
+                               }
+                               break;
+
+                               //
+                               // There is no overflow checking on left shift
+                               //
+                       case Binary.Operator.LeftShift:
+                               IntConstant ic = right.ToInt (loc);
+                               if (ic == null){
+                                       Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
+                                       return null;
+                               }
+                               int lshift_val = ic.Value;
+
+                               IntConstant lic;
+                               if ((lic = left.ConvertToInt ()) != null)
+                                       return new IntConstant (lic.Value << lshift_val);
+
+                               UIntConstant luic;
+                               if ((luic = left.ConvertToUInt ()) != null)
+                                       return new UIntConstant (luic.Value << lshift_val);
+
+                               LongConstant llc;
+                               if ((llc = left.ConvertToLong ()) != null)
+                                       return new LongConstant (llc.Value << lshift_val);
+
+                               ULongConstant lulc;
+                               if ((lulc = left.ConvertToULong ()) != null)
+                                       return new ULongConstant (lulc.Value << lshift_val);
+
+                               Binary.Error_OperatorCannotBeApplied (loc, "<<", lt, rt);
+                               break;
+
+                               //
+                               // There is no overflow checking on right shift
+                               //
+                       case Binary.Operator.RightShift:
+                               IntConstant sic = right.ToInt (loc);
+                               if (sic == null){
+                                       Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
+                                       return null;
+                               }
+                               int rshift_val = sic.Value;
+
+                               IntConstant ric;
+                               if ((ric = left.ConvertToInt ()) != null)
+                                       return new IntConstant (ric.Value >> rshift_val);
+
+                               UIntConstant ruic;
+                               if ((ruic = left.ConvertToUInt ()) != null)
+                                       return new UIntConstant (ruic.Value >> rshift_val);
+
+                               LongConstant rlc;
+                               if ((rlc = left.ConvertToLong ()) != null)
+                                       return new LongConstant (rlc.Value >> rshift_val);
+
+                               ULongConstant rulc;
+                               if ((rulc = left.ConvertToULong ()) != null)
+                                       return new ULongConstant (rulc.Value >> rshift_val);
+
+                               Binary.Error_OperatorCannotBeApplied (loc, ">>", lt, rt);
+                               break;
+
+                       case Binary.Operator.LogicalAnd:
+                               if (left is BoolConstant && right is BoolConstant){
+                                       return new BoolConstant (
+                                               ((BoolConstant) left).Value &&
+                                               ((BoolConstant) right).Value);
+                               }
+                               break;
+
+                       case Binary.Operator.LogicalOr:
+                               if (left is BoolConstant && right is BoolConstant){
+                                       return new BoolConstant (
+                                               ((BoolConstant) left).Value ||
+                                               ((BoolConstant) right).Value);
+                               }
+                               break;
+                               
+                       case Binary.Operator.Equality:
+                               if (left is BoolConstant && right is BoolConstant){
+                                       return new BoolConstant (
+                                               ((BoolConstant) left).Value ==
+                                               ((BoolConstant) right).Value);
+                               
+                               }
+                               if (left is NullLiteral){
+                                       if (right is NullLiteral)
+                                               return new BoolConstant (true);
+                                       else if (right is StringConstant)
+                                               return new BoolConstant (
+                                                       ((StringConstant) right).Value == null);
+                               } else if (right is NullLiteral){
+                                       if (left is NullLiteral)
+                                               return new BoolConstant (true);
+                                       else if (left is StringConstant)
+                                               return new BoolConstant (
+                                                       ((StringConstant) left).Value == null);
+                               }
+                               if (left is StringConstant && right is StringConstant){
+                                       return new BoolConstant (
+                                               ((StringConstant) left).Value ==
+                                               ((StringConstant) right).Value);
+                                       
+                               }
+
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value ==
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value ==
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value ==
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value ==
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value ==
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value ==
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+
+                       case Binary.Operator.Inequality:
+                               if (left is BoolConstant && right is BoolConstant){
+                                       return new BoolConstant (
+                                               ((BoolConstant) left).Value !=
+                                               ((BoolConstant) right).Value);
+                               }
+                               if (left is NullLiteral){
+                                       if (right is NullLiteral)
+                                               return new BoolConstant (false);
+                                       else if (right is StringConstant)
+                                               return new BoolConstant (
+                                                       ((StringConstant) right).Value != null);
+                               } else if (right is NullLiteral){
+                                       if (left is NullLiteral)
+                                               return new BoolConstant (false);
+                                       else if (left is StringConstant)
+                                               return new BoolConstant (
+                                                       ((StringConstant) left).Value != null);
+                               }
+                               if (left is StringConstant && right is StringConstant){
+                                       return new BoolConstant (
+                                               ((StringConstant) left).Value !=
+                                               ((StringConstant) right).Value);
+                                       
+                               }
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value !=
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value !=
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value !=
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value !=
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value !=
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value !=
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+
+                       case Binary.Operator.LessThan:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value <
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value <
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value <
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value <
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value <
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value <
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+                               
+                       case Binary.Operator.GreaterThan:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value >
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value >
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value >
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value >
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value >
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value >
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+
+                       case Binary.Operator.GreaterThanOrEqual:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value >=
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value >=
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value >=
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value >=
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value >=
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value >=
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+
+                       case Binary.Operator.LessThanOrEqual:
+                               DoConstantNumericPromotions (ec, oper, ref left, ref right, loc);
+                               if (left == null || right == null)
+                                       return null;
+
+                               bool_res = false;
+                               if (left is DoubleConstant)
+                                       bool_res = ((DoubleConstant) left).Value <=
+                                               ((DoubleConstant) right).Value;
+                               else if (left is FloatConstant)
+                                       bool_res = ((FloatConstant) left).Value <=
+                                               ((FloatConstant) right).Value;
+                               else if (left is ULongConstant)
+                                       bool_res = ((ULongConstant) left).Value <=
+                                               ((ULongConstant) right).Value;
+                               else if (left is LongConstant)
+                                       bool_res = ((LongConstant) left).Value <=
+                                               ((LongConstant) right).Value;
+                               else if (left is UIntConstant)
+                                       bool_res = ((UIntConstant) left).Value <=
+                                               ((UIntConstant) right).Value;
+                               else if (left is IntConstant)
+                                       bool_res = ((IntConstant) left).Value <=
+                                               ((IntConstant) right).Value;
+                               else
+                                       return null;
+
+                               return new BoolConstant (bool_res);
+                       }
+                                       
+                       return null;
+               }
+       }
+}
diff --git a/mcs/bmcs/class.cs b/mcs/bmcs/class.cs
new file mode 100644 (file)
index 0000000..d9eb566
--- /dev/null
@@ -0,0 +1,7904 @@
+//
+// class.cs: Class and Struct handlers
+//
+// Authors: Miguel de Icaza (miguel@gnu.org)
+//          Martin Baulig (martin@ximian.com)
+//          Marek Safar (marek.safar@seznam.cz)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
+//
+//
+//  2002-10-11  Miguel de Icaza  <miguel@ximian.com>
+//
+//     * class.cs: Following the comment from 2002-09-26 to AddMethod, I
+//     have fixed a remaining problem: not every AddXXXX was adding a
+//     fully qualified name.  
+//
+//     Now everyone registers a fully qualified name in the DeclSpace as
+//     being defined instead of the partial name.  
+//
+//     Downsides: we are slower than we need to be due to the excess
+//     copies and the names being registered this way.  
+//
+//     The reason for this is that we currently depend (on the corlib
+//     bootstrap for instance) that types are fully qualified, because
+//     we dump all the types in the namespace, and we should really have
+//     types inserted into the proper namespace, so we can only store the
+//     basenames in the defined_names array.
+//
+//
+#define CACHE
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Security.Permissions;
+using System.Xml;
+
+using Mono.CompilerServices.SymbolWriter;
+
+namespace Mono.CSharp {
+
+       public enum Kind {
+               Root,
+               Struct,
+               Class,
+               Interface
+       }
+
+       /// <summary>
+       ///   This is the base class for structs and classes.  
+       /// </summary>
+       public abstract class TypeContainer : DeclSpace, IMemberContainer {
+
+               public class MemberCoreArrayList: ArrayList
+               {
+                       /// <summary>
+                       ///   Defines the MemberCore objects that are in this array
+                       /// </summary>
+                       public virtual void DefineContainerMembers ()
+                       {
+                               foreach (MemberCore mc in this) {
+                                       mc.Define ();
+                               }
+                       }
+
+                       public virtual void Emit ()
+                       {
+                               foreach (MemberCore mc in this)
+                                       mc.Emit ();
+                       }
+               }
+
+               public class MethodArrayList: MemberCoreArrayList
+               {
+                       [Flags]
+                       enum CachedMethods {
+                               Equals                  = 1,
+                               GetHashCode             = 1 << 1
+                       }
+                       CachedMethods cached_method;
+                       TypeContainer container;
+
+                       public MethodArrayList (TypeContainer container)
+                       {
+                               this.container = container;
+                       }
+                       /// <summary>
+                       /// Method container contains Equals method
+                       /// </summary>
+                       public bool HasEquals {
+                               set {
+                                       cached_method |= CachedMethods.Equals;
+                               }
+                               get {
+                                       return (cached_method & CachedMethods.Equals) != 0;
+                               }
+                       }
+                       /// <summary>
+                       /// Method container contains GetHashCode method
+                       /// </summary>
+                       public bool HasGetHashCode {
+                               set {
+                                       cached_method |= CachedMethods.GetHashCode;
+                               }
+                               get {
+                                       return (cached_method & CachedMethods.GetHashCode) != 0;
+                               }
+                       }
+                       public override void DefineContainerMembers ()
+                       {
+                               base.DefineContainerMembers ();
+                               if ((RootContext.WarningLevel >= 3) && HasEquals && !HasGetHashCode) {
+                                       Report.Warning (659, container.Location, "'{0}' overrides Object.Equals(object) but does not override Object.GetHashCode()", container.GetSignatureForError ());
+                               }
+                       }
+               }
+
+               public sealed class IndexerArrayList: MemberCoreArrayList
+               {
+                       /// <summary>
+                       /// The indexer name for this container
+                       /// </summary>
+                       public string IndexerName = DefaultIndexerName;
+
+                       bool seen_normal_indexers = false;
+
+                       TypeContainer container;
+
+                       public IndexerArrayList (TypeContainer container)
+                       {
+                               this.container = container;
+                       }
+
+                       /// <summary>
+                       /// Defines the indexers, and also verifies that the IndexerNameAttribute in the
+                       /// class is consistent.  Either it is `Item' or it is the name defined by all the
+                       /// indexers with the `IndexerName' attribute.
+                       ///
+                       /// Turns out that the IndexerNameAttribute is applied to each indexer,
+                       /// but it is never emitted, instead a DefaultMember attribute is attached
+                       /// to the class.
+                       /// </summary>
+                       public override void DefineContainerMembers()
+                       {
+                               base.DefineContainerMembers ();
+
+                               string class_indexer_name = null;
+
+                               //
+                               // If there's both an explicit and an implicit interface implementation, the
+                               // explicit one actually implements the interface while the other one is just
+                               // a normal indexer.  See bug #37714.
+                               //
+
+                               // Invariant maintained by AddIndexer(): All explicit interface indexers precede normal indexers
+                               foreach (Indexer i in this) {
+                                       if (i.InterfaceType != null) {
+                                               if (seen_normal_indexers)
+                                                       throw new Exception ("Internal Error: 'Indexers' array not sorted properly.");
+                                               continue;
+                                       }
+
+                                       seen_normal_indexers = true;
+
+                                       if (class_indexer_name == null) {
+                                               class_indexer_name = i.ShortName;
+                                               continue;
+                                       }
+
+                                       if (i.ShortName != class_indexer_name)
+                                               Report.Error (668, i.Location, "Two indexers have different names; the IndexerName attribute must be used with the same name on every indexer within a type");
+                               }
+
+                               if (class_indexer_name != null)
+                                       IndexerName = class_indexer_name;
+                       }
+
+                       public override void Emit ()
+                       {
+                               base.Emit ();
+
+                               if (!seen_normal_indexers)
+                                       return;
+
+                               CustomAttributeBuilder cb = new CustomAttributeBuilder (TypeManager.default_member_ctor, new string [] { IndexerName });
+                               container.TypeBuilder.SetCustomAttribute (cb);
+                       }
+               }
+
+               public class OperatorArrayList: MemberCoreArrayList
+               {
+                       TypeContainer container;
+
+                       public OperatorArrayList (TypeContainer container)
+                       {
+                               this.container = container;
+                       }
+
+                       //
+                       // Operator pair checking
+                       //
+                       class OperatorEntry
+                       {
+                               public int flags;
+                               public Type ret_type;
+                               public Type type1, type2;
+                               public Operator op;
+                               public Operator.OpType ot;
+                               
+                               public OperatorEntry (int f, Operator o)
+                               {
+                                       flags = f;
+
+                                       ret_type = o.OperatorMethod.ReturnType;
+                                       Type [] pt = o.OperatorMethod.ParameterTypes;
+                                       type1 = pt [0];
+                                       type2 = pt [1];
+                                       op = o;
+                                       ot = o.OperatorType;
+                               }
+
+                               public override int GetHashCode ()
+                               {       
+                                       return ret_type.GetHashCode ();
+                               }
+
+                               public override bool Equals (object o)
+                               {
+                                       OperatorEntry other = (OperatorEntry) o;
+
+                                       if (other.ret_type != ret_type)
+                                               return false;
+                                       if (other.type1 != type1)
+                                               return false;
+                                       if (other.type2 != type2)
+                                               return false;
+                                       return true;
+                               }
+                       }
+                               
+                       //
+                       // Checks that some operators come in pairs:
+                       //  == and !=
+                       // > and <
+                       // >= and <=
+                       // true and false
+                       //
+                       // They are matched based on the return type and the argument types
+                       //
+                       void CheckPairedOperators ()
+                       {
+                               Hashtable pairs = new Hashtable (null, null);
+                               Operator true_op = null;
+                               Operator false_op = null;
+                               bool has_equality_or_inequality = false;
+                               
+                               // Register all the operators we care about.
+                               foreach (Operator op in this){
+                                       int reg = 0;
+                                       
+                                       switch (op.OperatorType){
+                                       case Operator.OpType.Equality:
+                                               reg = 1;
+                                               has_equality_or_inequality = true;
+                                               break;
+                                       case Operator.OpType.Inequality:
+                                               reg = 2;
+                                               has_equality_or_inequality = true;
+                                               break;
+
+                                       case Operator.OpType.True:
+                                               true_op = op;
+                                               break;
+                                       case Operator.OpType.False:
+                                               false_op = op;
+                                               break;
+                                               
+                                       case Operator.OpType.GreaterThan:
+                                               reg = 1; break;
+                                       case Operator.OpType.LessThan:
+                                               reg = 2; break;
+                                               
+                                       case Operator.OpType.GreaterThanOrEqual:
+                                               reg = 1; break;
+                                       case Operator.OpType.LessThanOrEqual:
+                                               reg = 2; break;
+                                       }
+                                       if (reg == 0)
+                                               continue;
+
+                                       OperatorEntry oe = new OperatorEntry (reg, op);
+
+                                       object o = pairs [oe];
+                                       if (o == null)
+                                               pairs [oe] = oe;
+                                       else {
+                                               oe = (OperatorEntry) o;
+                                               oe.flags |= reg;
+                                       }
+                               }
+
+                               if (true_op != null){
+                                       if (false_op == null)
+                                               Report.Error (216, true_op.Location, "operator true requires a matching operator false");
+                               } else if (false_op != null)
+                                       Report.Error (216, false_op.Location, "operator false requires a matching operator true");
+                               
+                               //
+                               // Look for the mistakes.
+                               //
+                               foreach (DictionaryEntry de in pairs){
+                                       OperatorEntry oe = (OperatorEntry) de.Key;
+
+                                       if (oe.flags == 3)
+                                               continue;
+
+                                       string s = "";
+                                       switch (oe.ot){
+                                       case Operator.OpType.Equality:
+                                               s = "!=";
+                                               break;
+                                       case Operator.OpType.Inequality: 
+                                               s = "==";
+                                               break;
+                                       case Operator.OpType.GreaterThan: 
+                                               s = "<";
+                                               break;
+                                       case Operator.OpType.LessThan:
+                                               s = ">";
+                                               break;
+                                       case Operator.OpType.GreaterThanOrEqual:
+                                               s = "<=";
+                                               break;
+                                       case Operator.OpType.LessThanOrEqual:
+                                               s = ">=";
+                                               break;
+                                       }
+                                       Report.Error (216, oe.op.Location,
+                                                       "The operator `" + oe.op + "' requires a matching operator `" + s + "' to also be defined");
+                               }
+
+                               if (has_equality_or_inequality && (RootContext.WarningLevel > 2)) {
+                                       if (container.Methods == null || !container.Methods.HasEquals)
+                                               Report.Warning (660, container.Location, "'{0}' defines operator == or operator != but does not override Object.Equals(object o)", container.GetSignatureForError ());
+                                       if (container.Methods == null || !container.Methods.HasGetHashCode)
+                                               Report.Warning (661, container.Location, "'{0}' defines operator == or operator != but does not override Object.GetHashCode()", container.GetSignatureForError ());
+                               }
+                       }
+
+                       public override void DefineContainerMembers ()
+                       {
+                               base.DefineContainerMembers ();
+                               CheckPairedOperators ();
+                       }
+               }
+
+
+               // Whether this is a struct, class or interface
+               public readonly Kind Kind;
+
+               // Holds a list of classes and structures
+               ArrayList types;
+
+               // Holds the list of properties
+               MemberCoreArrayList properties;
+
+               // Holds the list of enumerations
+               MemberCoreArrayList enums;
+
+               // Holds the list of delegates
+               MemberCoreArrayList delegates;
+               
+               // Holds the list of constructors
+               protected MemberCoreArrayList instance_constructors;
+
+               // Holds the list of fields
+               MemberCoreArrayList fields;
+
+               // Holds a list of fields that have initializers
+               protected ArrayList initialized_fields;
+
+               // Holds a list of static fields that have initializers
+               protected ArrayList initialized_static_fields;
+
+               // Holds the list of constants
+               MemberCoreArrayList constants;
+
+               // Holds the list of
+               MemberCoreArrayList interfaces;
+
+               // Holds the methods.
+               MethodArrayList methods;
+
+               // Holds the events
+               protected MemberCoreArrayList events;
+
+               // Holds the indexers
+               IndexerArrayList indexers;
+
+               // Holds the operators
+               MemberCoreArrayList operators;
+
+               // Holds the iterators
+               ArrayList iterators;
+
+               // Holds the parts of a partial class;
+               ArrayList parts;
+
+               //
+               // Pointers to the default constructor and the default static constructor
+               //
+               protected Constructor default_constructor;
+               protected Constructor default_static_constructor;
+
+               //
+               // Whether we have at least one non-static field
+               //
+               bool have_nonstatic_fields = false;
+               
+               //
+               // This one is computed after we can distinguish interfaces
+               // from classes from the arraylist `type_bases' 
+               //
+               string base_class_name;
+               TypeExpr parent_type;
+
+               ArrayList type_bases;
+
+               bool members_defined;
+               bool members_defined_ok;
+
+               // The interfaces we implement.
+               protected Type[] ifaces;
+               protected Type ptype;
+
+               // The parent member cache and our member cache
+               MemberCache parent_cache;
+               MemberCache member_cache;
+
+               public const string DefaultIndexerName = "Item";
+
+               Type GenericType;
+
+               public TypeContainer (NamespaceEntry ns, TypeContainer parent, MemberName name,
+                                     Attributes attrs, Kind kind, Location l)
+                       : base (ns, parent, name, attrs, l)
+               {
+                       this.Kind = kind;
+
+                       types = new ArrayList ();
+
+                       base_class_name = null;
+               }
+
+               public bool AddToMemberContainer (MemberCore symbol, bool is_method)
+               {
+                       return AddToContainer (symbol, is_method, String.Concat (Name, '.', symbol.Name), symbol.Name);
+               }
+
+               bool AddToTypeContainer (DeclSpace ds)
+               {
+                       return AddToContainer (ds, false, ds.Name, ds.Basename);
+               }
+
+               public void AddConstant (Const constant)
+               {
+                       if (!AddToMemberContainer (constant, false))
+                               return;
+
+                       if (constants == null)
+                               constants = new MemberCoreArrayList ();
+
+                       constants.Add (constant);
+               }
+
+               public void AddEnum (Mono.CSharp.Enum e)
+               {
+                       if (!AddToTypeContainer (e))
+                               return;
+
+                       if (enums == null)
+                               enums = new MemberCoreArrayList ();
+
+                       enums.Add (e);
+               }
+               
+               public void AddClassOrStruct (TypeContainer c)
+               {
+                       if (!AddToTypeContainer (c))
+                               return;
+
+                       types.Add (c);
+               }
+
+               public void AddDelegate (Delegate d)
+               {
+                       if (!AddToTypeContainer (d))
+                               return;
+
+                       if (delegates == null)
+                               delegates = new MemberCoreArrayList ();
+                       
+                       delegates.Add (d);
+               }
+
+               public void AddMethod (Method method)
+               {
+                       if (!AddToMemberContainer (method, true))
+                               return;
+
+                       if (methods == null)
+                               methods = new MethodArrayList (this);
+
+                       if (method.Name.IndexOf ('.') != -1)
+                               methods.Insert (0, method);
+                       else 
+                               methods.Add (method);
+               }
+
+               public void AddConstructor (Constructor c)
+               {
+                       if (c.Name != Basename) {
+                               Report.Error (1520, c.Location, "Class, struct, or interface method must have a return type");
+                       }
+
+                       bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
+                       
+                       if (is_static){
+                               if (default_static_constructor != null) {
+                                       Report.SymbolRelatedToPreviousError (default_static_constructor);
+                                       Report.Error (111, c.Location, "Type '{0}' already defines a member " +
+                                                     "called '{1}' with the same parameter types", Name, c.Name);
+                                       return;
+                               }
+
+                               default_static_constructor = c;
+                       } else {
+                               if (c.IsDefault ()){
+                                       if (default_constructor != null) {
+                                               Report.SymbolRelatedToPreviousError (default_constructor);
+                                               Report.Error (111, c.Location, "Type '{0}' already defines a member " +
+                                                     "called '{1}' with the same parameter types", Name, c.Name);
+                                               return;
+                                       }
+                                       default_constructor = c;
+                               }
+                               
+                               if (instance_constructors == null)
+                                       instance_constructors = new MemberCoreArrayList ();
+                               
+                               instance_constructors.Add (c);
+                       }
+               }
+               
+               public void AddInterface (TypeContainer iface)
+               {
+                       if (!AddToTypeContainer (iface))
+                               return;
+
+                       if (interfaces == null) {
+                               interfaces = new MemberCoreArrayList ();
+                       }
+
+                       interfaces.Add (iface);
+               }
+
+               public void AddField (Field field)
+               {
+                       if (!AddToMemberContainer (field, false))
+                               return;
+
+                       if (fields == null)
+                               fields = new MemberCoreArrayList ();
+                       
+                       fields.Add (field);
+                       
+                       if (field.HasInitializer){
+                               if ((field.ModFlags & Modifiers.STATIC) != 0){
+                                       if (initialized_static_fields == null)
+                                               initialized_static_fields = new ArrayList ();
+
+                                       initialized_static_fields.Add (field);
+
+                               } else {
+                                       if (initialized_fields == null)
+                                               initialized_fields = new ArrayList ();
+                               
+                                       initialized_fields.Add (field);
+                               }
+                       }
+
+                       if ((field.ModFlags & Modifiers.STATIC) == 0)
+                               have_nonstatic_fields = true;
+               }
+
+               public void AddProperty (Property prop)
+               {
+                       if (!AddToMemberContainer (prop, false) || 
+                           !AddToMemberContainer (prop.Get, true) || !AddToMemberContainer (prop.Set, true))
+                               return;
+
+                       if (properties == null)
+                               properties = new MemberCoreArrayList ();
+
+                       if (prop.Name.IndexOf ('.') != -1)
+                               properties.Insert (0, prop);
+                       else
+                               properties.Add (prop);
+               }
+
+               public void AddEvent (Event e)
+               {
+                       if (!AddToMemberContainer (e, false))
+                               return;
+
+                       if (e is EventProperty) {
+                               if (!AddToMemberContainer (e.Add, true))
+                                       return;
+
+                               if (!AddToMemberContainer (e.Remove, true))
+                                       return;
+                       }
+
+                       if (events == null)
+                               events = new MemberCoreArrayList ();
+
+                       events.Add (e);
+               }
+
+               /// <summary>
+               /// Indexer has special handling in constrast to other AddXXX because the name can be driven by IndexerNameAttribute
+               /// </summary>
+               public void AddIndexer (Indexer i)
+               {
+                       if (indexers == null)
+                               indexers = new IndexerArrayList (this);
+
+                       if (i.IsExplicitImpl)
+                               indexers.Insert (0, i);
+                       else
+                               indexers.Add (i);
+               }
+
+               public void AddOperator (Operator op)
+               {
+                       if (!AddToMemberContainer (op, true))
+                               return;
+
+                       if (operators == null)
+                               operators = new OperatorArrayList (this);
+
+                       operators.Add (op);
+               }
+
+               public void AddIterator (Iterator i)
+               {
+                       if (iterators == null)
+                               iterators = new ArrayList ();
+
+                       iterators.Add (i);
+               }
+
+               public void AddType (TypeContainer tc)
+               {
+                       types.Add (tc);
+               }
+
+               public void AddPart (ClassPart part)
+               {
+                       if (parts == null)
+                               parts = new ArrayList ();
+
+                       parts.Add (part);
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type == TypeManager.default_member_type) {
+                               if (Indexers != null) {
+                                       Report.Error (646, a.Location,
+                                                     "Cannot specify the DefaultMember attribute on" +
+                                                     " a type containing an indexer");
+                                       return;
+                               }
+                       }
+                       
+                       base.ApplyAttributeBuilder (a, cb);
+               } 
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               throw new NotSupportedException ();
+                       }
+               }
+
+               public ArrayList Types {
+                       get {
+                               return types;
+                       }
+               }
+
+               public MethodArrayList Methods {
+                       get {
+                               return methods;
+                       }
+               }
+
+               public ArrayList Constants {
+                       get {
+                               return constants;
+                       }
+               }
+
+               public ArrayList Interfaces {
+                       get {
+                               return interfaces;
+                       }
+               }
+
+               public ArrayList Iterators {
+                       get {
+                               return iterators;
+                       }
+               }
+               
+               public string Base {
+                       get {
+                               return base_class_name;
+                       }
+               }
+               
+               public ArrayList Bases {
+                       get {
+                               return type_bases;
+                       }
+
+                       set {
+                               type_bases = value;
+                       }
+               }
+
+               public ArrayList Fields {
+                       get {
+                               return fields;
+                       }
+               }
+
+               public ArrayList InstanceConstructors {
+                       get {
+                               return instance_constructors;
+                       }
+               }
+
+               public ArrayList Properties {
+                       get {
+                               return properties;
+                       }
+               }
+
+               public ArrayList Events {
+                       get {
+                               return events;
+                       }
+               }
+               
+               public ArrayList Enums {
+                       get {
+                               return enums;
+                       }
+               }
+
+               public ArrayList Indexers {
+                       get {
+                               return indexers;
+                       }
+               }
+
+               public ArrayList Operators {
+                       get {
+                               return operators;
+                       }
+               }
+
+               public ArrayList Delegates {
+                       get {
+                               return delegates;
+                       }
+               }
+               
+               public ArrayList Parts {
+                       get {
+                               return parts;
+                       }
+               }
+
+               public virtual TypeAttributes TypeAttr {
+                       get {
+                               return Modifiers.TypeAttr (ModFlags, this);
+                       }
+               }
+
+               public string IndexerName {
+                       get {
+                               return indexers == null ? DefaultIndexerName : indexers.IndexerName;
+                       }
+               }
+
+               //
+               // Emits the instance field initializers
+               //
+               public bool EmitFieldInitializers (EmitContext ec)
+               {
+                       ArrayList fields;
+                       Expression instance_expr;
+                       
+                       if (ec.IsStatic){
+                               fields = initialized_static_fields;
+                               instance_expr = null;
+                       } else {
+                               fields = initialized_fields;
+                               instance_expr = new This (Location.Null).Resolve (ec);
+                       }
+
+                       if (fields == null)
+                               return true;
+
+                       foreach (Field f in fields){
+                               Expression e = f.GetInitializerExpression (ec);
+                               if (e == null)
+                                       return false;
+
+                               Location l = f.Location;
+                               FieldExpr fe = new FieldExpr (f.FieldBuilder, l);
+                               fe.InstanceExpression = instance_expr;
+                               fe.IsFieldInitializer = true;
+
+                               ExpressionStatement a = new Assign (fe, e, l);
+
+                               a = a.ResolveStatement (ec);
+                               if (a == null)
+                                       return false;
+
+                               a.EmitStatement (ec);
+                       }
+
+                       return true;
+               }
+               
+               //
+               // Defines the default constructors
+               //
+               protected void DefineDefaultConstructor (bool is_static)
+               {
+                       Constructor c;
+
+                       // The default constructor is public
+                       // If the class is abstract, the default constructor is protected
+                       // The default static constructor is private
+
+                       int mods = Modifiers.PUBLIC;
+                       if (is_static)
+                               mods = Modifiers.STATIC | Modifiers.PRIVATE;
+                       else if ((ModFlags & Modifiers.ABSTRACT) != 0)
+                               mods = Modifiers.PROTECTED;
+
+                       c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
+                                            new ConstructorBaseInitializer (
+                                                    null, Parameters.EmptyReadOnlyParameters,
+                                                    Location),
+                                            Location);
+                       
+                       AddConstructor (c);
+                       
+                       c.Block = new ToplevelBlock (null, Location);
+                       
+               }
+
+               /// <remarks>
+               ///  The pending methods that need to be implemented
+               //   (interfaces or abstract methods)
+               /// </remarks>
+               public PendingImplementation Pending;
+
+               public abstract void Register ();
+
+               public abstract PendingImplementation GetPendingImplementations ();
+
+               TypeExpr[] GetPartialBases (out TypeExpr parent, out bool error)
+               {
+                       ArrayList ifaces = new ArrayList ();
+
+                       parent = null;
+                       Location parent_loc = Location.Null;
+
+                       foreach (ClassPart part in parts) {
+                               TypeExpr new_parent;
+                               TypeExpr[] new_ifaces;
+
+                               new_ifaces = part.GetClassBases (out new_parent, out error);
+                               if (error)
+                                       return null;
+
+                               if ((parent != null) && (new_parent != null) &&
+                                   !parent.Equals (new_parent)) {
+                                       Report.Error (263, part.Location,
+                                                     "Partial declarations of `{0}' must " +
+                                                     "not specify different base classes",
+                                                     Name);
+
+                                       if (!Location.IsNull (parent_loc))
+                                               Report.LocationOfPreviousError (parent_loc);
+
+                                       error = true;
+                                       return null;
+                               }
+
+                               if ((parent == null) && (new_parent != null)) {
+                                       parent = new_parent;
+                                       parent_loc = part.Location;
+                               }
+
+                               if (new_ifaces == null)
+                                       continue;
+
+                               foreach (TypeExpr iface in new_ifaces) {
+                                       bool found = false;
+                                       foreach (TypeExpr old_iface in ifaces) {
+                                               if (old_iface.Equals (iface)) {
+                                                       found = true;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (!found)
+                                               ifaces.Add (iface);
+                               }
+                       }
+
+                       error = false;
+
+                       TypeExpr[] retval = new TypeExpr [ifaces.Count];
+                       ifaces.CopyTo (retval, 0);
+                       return retval;
+               }
+
+               TypeExpr[] GetNormalBases (out TypeExpr parent, out bool error)
+               {
+                       parent = null;
+
+                       int count = Bases.Count;
+                       int start, i, j;
+
+                       if (Kind == Kind.Class){
+                               TypeExpr name = ResolveTypeExpr ((Expression) Bases [0], Location);
+
+                               if (name == null){
+                                       error = true;
+                                       return null;
+                               }
+
+                               if (name.IsClass){
+                                       parent = name;
+                                       start = 1;
+                               } else {
+                                       start = 0;
+                               }
+                       } else {
+                               start = 0;
+                       }
+
+                       TypeExpr [] ifaces = new TypeExpr [count-start];
+                       
+                       for (i = start, j = 0; i < count; i++, j++){
+                               Expression name = (Expression) Bases [i];
+                               TypeExpr resolved = ResolveTypeExpr (name, Location);
+                               if (resolved == null) {
+                                       error = true;
+                                       return null;
+                               }
+                               
+                               ifaces [j] = resolved;
+                       }
+
+                       error = false;
+                       return ifaces;
+               }
+
+               /// <summary>
+               ///   This function computes the Base class and also the
+               ///   list of interfaces that the class or struct @c implements.
+               ///   
+               ///   The return value is an array (might be null) of
+               ///   interfaces implemented (as Types).
+               ///   
+               ///   The @parent argument is set to the parent object or null
+               ///   if this is `System.Object'. 
+               /// </summary>
+               TypeExpr [] GetClassBases (out TypeExpr parent, out bool error)
+               {
+                       int i;
+
+                       error = false;
+
+                       TypeExpr[] ifaces;
+
+                       if (parts != null)
+                               ifaces = GetPartialBases (out parent, out error);
+                       else if (Bases == null){
+                               parent = null;
+                               return null;
+                       } else
+                               ifaces = GetNormalBases (out parent, out error);
+
+                       if (error)
+                               return null;
+
+                       if ((parent != null) && (Kind == Kind.Class)){
+                               if (parent is TypeParameterExpr){
+                                       Report.Error (
+                                               689, parent.Location,
+                                               "Type parameter `{0}' can not be used as a " +
+                                               "base class or interface", parent.Name);
+                                       error = true;
+                                       return null;
+                               }
+
+                               if (IsGeneric && parent.IsAttribute){
+                                       Report.Error (
+                                               698, parent.Location,
+                                               "A generic type cannot derive from `{0}' " +
+                                               "because it is an attribute class",
+                                               parent.Name);
+                                       error = true;
+                                       return null;
+                               }
+
+                               if (parent.IsSealed){
+                                       error = true;
+                                       Report.SymbolRelatedToPreviousError (parent.Type);
+                                       if (parent.Type.IsAbstract) {
+                                               Report.Error (709, Location, "'{0}': Cannot derive from static class", GetSignatureForError ());
+                                       } else {
+                                               Report.Error (509, Location, "'{0}': Cannot derive from sealed class", GetSignatureForError ());
+                                       }
+                                       return null;
+                               }
+
+                               if (!parent.CanInheritFrom ()){
+                                       Report.Error (644, Location,
+                                                     "`{0}' cannot inherit from special class `{1}'",
+                                                     Name, parent_type.Name);
+                                       error = true;
+                                       return null;
+                               }
+
+                               if (!parent.AsAccessible (this, ModFlags)) {
+                                       Report.SymbolRelatedToPreviousError (parent.Type);
+                                       Report.Error (60, Location, "Inconsistent accessibility: base class '{0}' is less accessible than class '{1}'", 
+                                               TypeManager.CSharpName (parent.Type), GetSignatureForError ());
+                               }
+                       }
+
+                       if (parent != null)
+                               base_class_name = parent.Name;
+
+                       if (ifaces == null)
+                               return null;
+
+                       int count = ifaces != null ? ifaces.Length : 0;
+
+                       for (i = 0; i < count; i++) {
+                               TypeExpr iface = (TypeExpr) ifaces [i];
+
+                               if ((Kind != Kind.Class) && !iface.IsInterface){
+                                       string what = Kind == Kind.Struct ?
+                                               "Struct" : "Interface";
+
+                                       Report.Error (527, Location,
+                                                     "In {0} `{1}', type `{2}' is not "+
+                                                     "an interface", what, Name, iface.Name);
+                                       error = true;
+                                       return null;
+                               }
+
+                               if (iface.IsClass) {
+                                       if (parent != null)
+                                               Report.Error (1721, Location,
+                                                             "In Class `{0}', `{1}' is not an interface, and a base class has already been defined",
+                                                             Name, iface.Name);
+                                       else {
+                                               Report.Error (1722, Location,
+                                                             "In Class `{0}', `{1}' is not " +
+                                                             "an interface, a base class must be listed first", Name, iface.Name);
+                                       }
+                                       error = true;
+                                       return null;
+                               }
+  
+                               for (int x = 0; x < i; x++) {
+                                       if (iface.Equals (ifaces [x])) {
+                                               Report.Error (528, Location,
+                                                             "`{0}' is already listed in " +
+                                                             "interface list", iface.Name);
+                                               error = true;
+                                               return null;
+                                       }
+                               }
+
+                               if ((Kind == Kind.Interface) &&
+                                   !iface.AsAccessible (Parent, ModFlags))
+                                       Report.Error (61, Location,
+                                                     "Inconsistent accessibility: base " +
+                                                     "interface `{0}' is less accessible " +
+                                                     "than interface `{1}'", iface.Name,
+                                                     Name);
+                       }
+
+                       return ifaces;
+               }
+
+               bool CheckGenericInterfaces (Type[] ifaces)
+               {
+                       ArrayList already_checked = new ArrayList ();
+
+                       for (int i = 0; i < ifaces.Length; i++) {
+                               Type iface = ifaces [i];
+                               foreach (Type t in already_checked) {
+                                       if (iface == t)
+                                               continue;
+
+                                       Type[] infered = new Type [CountTypeParameters];
+                                       if (!TypeManager.MayBecomeEqualGenericInstances (iface, t, infered, null))
+                                               continue;
+
+                                       Report.Error (
+                                               695, Location,
+                                               "`{0}' cannot implement both `{1}' and `{2}' " +
+                                               "because they may unify for some type " +
+                                               "parameter substitutions",
+                                               TypeManager.GetFullName (TypeBuilder),
+                                               iface, t);
+                                       return false;
+                               }
+
+                               already_checked.Add (iface);
+                       }
+
+                       return true;
+               }
+
+               bool error = false;
+               
+               //
+               // Defines the type in the appropriate ModuleBuilder or TypeBuilder.
+               //
+               public override TypeBuilder DefineType ()
+               {
+                       TypeExpr parent;
+
+                       if (error)
+                               return null;
+
+                       if (TypeBuilder != null)
+                               return TypeBuilder;
+
+                       ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
+
+                       TypeAttributes type_attributes = TypeAttr;
+
+                       try {
+                               if (IsTopLevel){
+                                       if (TypeManager.NamespaceClash (Name, Location)) {
+                                               error = true;
+                                               return null;
+                                       }
+
+                                       ModuleBuilder builder = CodeGen.Module.Builder;
+                                       TypeBuilder = builder.DefineType (
+                                               Name, type_attributes, null, null);
+                               } else {
+                                       TypeBuilder builder;
+                                       if (Parent.TypeBuilder != null)
+                                               builder = Parent.TypeBuilder;
+                                       else
+                                               builder = Parent.DefineType ();
+
+                                       if (builder == null) {
+                                               error = true;
+                                               return null;
+                                       }
+                               
+                                       TypeBuilder = builder.DefineNestedType (
+                                               MemberName.Basename, type_attributes,
+                                               null, null);
+                               }
+                       }
+                       catch (ArgumentException) {
+                               Report.RuntimeMissingSupport (Location, "static classes");
+                               return null;
+                       }
+
+                       TypeManager.AddUserType (Name, TypeBuilder, this);
+
+                       TypeExpr current_type = null;
+
+                       if (IsGeneric) {
+                               string[] param_names = new string [TypeParameters.Length];
+                               for (int i = 0; i < TypeParameters.Length; i++)
+                                       param_names [i] = TypeParameters [i].Name;
+
+                               GenericTypeParameterBuilder[] gen_params;
+                               gen_params = TypeBuilder.DefineGenericParameters (param_names);
+
+                               int offset = CountTypeParameters - CurrentTypeParameters.Length;
+                               for (int i = offset; i < gen_params.Length; i++)
+                                       CurrentTypeParameters [i - offset].Define (gen_params [i]);
+
+                               foreach (TypeParameter type_param in CurrentTypeParameters) {
+                                       if (!type_param.Resolve (this)) {
+                                               error = true;
+                                               return null;
+                                       }
+                               }
+
+                               for (int i = offset; i < gen_params.Length; i++)
+                                       CurrentTypeParameters [i - offset].DefineConstraints ();
+
+                               current_type = new ConstructedType (Name, TypeParameters, Location);
+                       }
+
+                       if (IsGeneric) {
+                               foreach (TypeParameter type_param in TypeParameters)
+                                       if (!type_param.DefineType (ec)) {
+                                               error = true;
+                                               return null;
+                                       }
+                       }
+
+                       if ((Kind == Kind.Struct) && TypeManager.value_type == null)
+                               throw new Exception ();
+
+                       TypeExpr[] iface_exprs = GetClassBases (out parent_type, out error); 
+                       if (error)
+                               return null;
+
+                       if (parent_type == null) {
+                               if (Kind == Kind.Class){
+                                       if (RootContext.StdLib)
+                                               parent_type = TypeManager.system_object_expr;
+                                       else if (Name != "System.Object")
+                                               parent_type = TypeManager.system_object_expr;
+                               } else if (Kind == Kind.Struct){
+                                       //
+                                       // If we are compiling our runtime,
+                                       // and we are defining ValueType, then our
+                                       // parent is `System.Object'.
+                                       //
+                                       if (!RootContext.StdLib && Name == "System.ValueType")
+                                               parent_type = TypeManager.system_object_expr;
+                                       else if (Kind == Kind.Struct)
+                                               parent_type = TypeManager.system_valuetype_expr;
+                               }
+                       }
+
+                       if (parent_type != null) {
+                               parent_type = parent_type.ResolveAsTypeTerminal (ec);
+                               if (parent_type == null) {
+                                       error = true;
+                                       return null;
+                               }
+
+                               ptype = parent_type.Type;
+                       }
+
+                       if (!CheckRecursiveDefinition ()) {
+                               error = true;
+                               return null;
+                       }
+
+                       if (ptype != null)
+                               TypeBuilder.SetParent (ptype);
+
+                       //
+                       // Structs with no fields need to have at least one byte.
+                       // The right thing would be to set the PackingSize in a DefineType
+                       // but there are no functions that allow interfaces *and* the size to
+                       // be specified.
+                       //
+
+                       if ((Kind == Kind.Struct) && !have_nonstatic_fields){
+                               TypeBuilder.DefineField ("$PRIVATE$", TypeManager.byte_type,
+                                                        FieldAttributes.Private);
+                       }
+
+                       // add interfaces that were not added at type creation
+                       if (iface_exprs != null) {
+                               ifaces = TypeManager.ExpandInterfaces (ec, iface_exprs);
+                               if (ifaces == null) {
+                                       error = true;
+                                       return null;
+                               }
+
+                               foreach (Type itype in ifaces)
+                                       TypeBuilder.AddInterfaceImplementation (itype);
+
+                               if (!CheckGenericInterfaces (ifaces)) {
+                                       error = true;
+                                       return null;
+                               }
+
+                               TypeManager.RegisterBuilder (TypeBuilder, ifaces);
+                       }
+
+                       if (IsGeneric) {
+                               foreach (TypeParameter type_param in TypeParameters)
+                                       if (!type_param.CheckDependencies (ec)) {
+                                               error = true;
+                                               return null;
+                                       }
+                       }
+
+                       if (current_type != null) {
+                               current_type = current_type.ResolveAsTypeTerminal (ec);
+                               if (current_type == null) {
+                                       error = true;
+                                       return null;
+                               }
+
+                               CurrentType = current_type.Type;
+                       }
+
+                       //
+                       // Finish the setup for the EmitContext
+                       //
+                       ec.ContainerType = TypeBuilder;
+
+                       if ((parent_type != null) && parent_type.IsAttribute) {
+                               RootContext.RegisterAttribute (this);
+                       } else if (!(this is Iterator))
+                               RootContext.RegisterOrder (this); 
+
+                       if (!DefineNestedTypes ()) {
+                               error = true;
+                               return null;
+                       }
+
+                       return TypeBuilder;
+               }
+
+               protected virtual bool DefineNestedTypes ()
+               {
+                       if (Interfaces != null) {
+                               foreach (TypeContainer iface in Interfaces)
+                                       if (iface.DefineType () == null)
+                                               return false;
+                       }
+                       
+                       if (Types != null) {
+                               foreach (TypeContainer tc in Types)
+                                       if (tc.DefineType () == null)
+                                               return false;
+                       }
+
+                       if (Delegates != null) {
+                               foreach (Delegate d in Delegates)
+                                       if (d.DefineType () == null)
+                                               return false;
+                       }
+
+                       if (Enums != null) {
+                               foreach (Enum en in Enums)
+                                       if (en.DefineType () == null)
+                                               return false;
+                       }
+
+                       if (Parts != null) {
+                               foreach (ClassPart part in Parts) {
+                                       part.TypeBuilder = TypeBuilder;
+                                       part.parent_type = parent_type;
+                                       part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
+                               }
+                       }
+
+                       return true;
+               }
+
+               protected bool CheckRecursiveDefinition ()
+               {
+                       if (InTransit) {
+                               Report.Error (146, Location,
+                                             "Class definition is circular: `{0}'",
+                                             GetSignatureForError ());
+                               error = true;
+                               return false;
+                       }
+
+                       InTransit = true;
+
+                       Type parent = ptype;
+                       if (parent != null) {
+                               if (parent.IsGenericInstance)
+                                       parent = parent.GetGenericTypeDefinition ();
+
+                               TypeContainer ptc = TypeManager.LookupTypeContainer (parent);
+                               if ((ptc != null) && !ptc.CheckRecursiveDefinition ())
+                                       return false;
+                       }
+
+                       InTransit = false;
+                       return true;
+               }
+
+               static void Error_KeywordNotAllowed (Location loc)
+               {
+                       Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
+               }
+
+               /// <summary>
+               ///   Populates our TypeBuilder with fields and methods
+               /// </summary>
+               public override bool DefineMembers (TypeContainer container)
+               {
+                       if (members_defined)
+                               return members_defined_ok;
+
+                       members_defined_ok = DoDefineMembers ();
+                       members_defined = true;
+
+                       return members_defined_ok;
+               }
+
+               protected virtual bool DoDefineMembers ()
+               {
+                       //
+                       // We need to be able to use the member cache while we are checking/defining
+                       //
+                       if (TypeBuilder.BaseType != null)
+                               parent_cache = TypeManager.LookupMemberCache (TypeBuilder.BaseType);
+
+                       if (TypeBuilder.IsInterface)
+                               parent_cache = TypeManager.LookupParentInterfacesCache (TypeBuilder);
+
+                       if (IsTopLevel) {
+                               if ((ModFlags & Modifiers.NEW) != 0)
+                                       Error_KeywordNotAllowed (Location);
+                       } else {
+                               // HACK: missing implemenation
+                               // This is not fully functional. Better way how to handle this is to have recursive definition of containers
+                               // instead of flat as we have now.
+                               // Now we are not able to check inner attribute class because its parent had not been defined.
+
+                               // TODO: remove this if
+                               if (Parent.MemberCache != null) {
+                                       MemberInfo conflict_symbol = Parent.MemberCache.FindMemberWithSameName (Basename, false, TypeBuilder);
+                                       if (conflict_symbol == null) {
+                                               if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0))
+                                                       Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError ());
+                                       } else {
+                                               if ((ModFlags & Modifiers.NEW) == 0) {
+                                                       Report.SymbolRelatedToPreviousError (conflict_symbol);
+                                                       Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError ());
+                                               }
+                                       }
+                               }
+                       }
+
+                       DefineContainerMembers (constants);
+                       DefineContainerMembers (fields);
+
+                       if ((Kind == Kind.Class) && !(this is ClassPart) && !(this is StaticClass)){
+                               if ((instance_constructors == null) &&
+                                   !(this is StaticClass)) {
+                                       if (default_constructor == null)
+                                               DefineDefaultConstructor (false);
+                               }
+
+                               if (initialized_static_fields != null &&
+                                   default_static_constructor == null)
+                                       DefineDefaultConstructor (true);
+                       }
+
+                       if (Kind == Kind.Struct){
+                               //
+                               // Structs can not have initialized instance
+                               // fields
+                               //
+                               if (initialized_static_fields != null &&
+                                   default_static_constructor == null)
+                                       DefineDefaultConstructor (true);
+
+                               if (initialized_fields != null)
+                                       ReportStructInitializedInstanceError ();
+                       }
+
+                       Pending = GetPendingImplementations ();
+
+                       if (parts != null) {
+                               foreach (ClassPart part in parts) {
+                                       if (!part.DefineMembers (this))
+                                               return false;
+                               }
+                       }
+                       
+                       //
+                       // Constructors are not in the defined_names array
+                       //
+                       DefineContainerMembers (instance_constructors);
+
+                       if (default_static_constructor != null)
+                               default_static_constructor.Define ();
+
+                       DefineContainerMembers (properties);
+                       DefineContainerMembers (events);
+                       DefineContainerMembers (indexers);
+                       DefineContainerMembers (methods);
+                       DefineContainerMembers (operators);
+                       DefineContainerMembers (enums);
+                       DefineContainerMembers (delegates);
+
+                       if (CurrentType != null) {
+                               GenericType = CurrentType;
+
+                               ec.ContainerType = GenericType;
+                       }
+
+
+#if CACHE
+                       if (!(this is ClassPart))
+                               member_cache = new MemberCache (this);
+#endif
+
+                       if (parts != null) {
+                               foreach (ClassPart part in parts)
+                                       part.member_cache = member_cache;
+                       }
+
+                       if (iterators != null) {
+                               foreach (Iterator iterator in iterators) {
+                                       if (iterator.DefineType () == null)
+                                               return false;
+                               }
+
+                               foreach (Iterator iterator in iterators) {
+                                       if (!iterator.DefineMembers (this))
+                                               return false;
+                               }
+                       }
+
+                       return true;
+               }
+
+               void ReportStructInitializedInstanceError ()
+               {
+                       string n = TypeBuilder.FullName;
+                       
+                       foreach (Field f in initialized_fields){
+                               Report.Error (
+                                       573, Location,
+                                       "`" + n + "." + f.Name + "': can not have " +
+                                       "instance field initializers in structs");
+                       }
+               }
+
+               protected virtual void DefineContainerMembers (MemberCoreArrayList mcal)
+               {
+                       if (mcal != null)
+                               mcal.DefineContainerMembers ();
+               }
+
+               public override bool Define ()
+               {
+                       if (parts != null) {
+                               foreach (ClassPart part in parts) {
+                                       if (!part.Define ())
+                                               return false;
+                               }
+                       }
+
+                       return true;
+               }
+
+               public MemberInfo FindMemberWithSameName (string name, bool ignore_methods)
+               {
+                       return ParentCache.FindMemberWithSameName (name, ignore_methods, null);
+               }
+
+               /// <summary>
+               ///   This function is based by a delegate to the FindMembers routine
+               /// </summary>
+               static bool AlwaysAccept (MemberInfo m, object filterCriteria)
+               {
+                       return true;
+               }
+
+               /// <summary>
+               ///   This filter is used by FindMembers, and we just keep
+               ///   a global for the filter to `AlwaysAccept'
+               /// </summary>
+               static MemberFilter accepting_filter;
+
+               
+               static TypeContainer ()
+               {
+                       accepting_filter = new MemberFilter (AlwaysAccept);
+               }
+               
+               public MethodInfo[] GetMethods ()
+               {
+                       ArrayList members = new ArrayList ();
+
+                       DefineMembers (null);
+
+                       if (methods != null) {
+                               int len = methods.Count;
+                               for (int i = 0; i < len; i++) {
+                                       Method m = (Method) methods [i];
+
+                                       members.Add (m.MethodBuilder);
+                               }
+                       }
+
+                       if (operators != null) {
+                               int len = operators.Count;
+                               for (int i = 0; i < len; i++) {
+                                       Operator o = (Operator) operators [i];
+
+                                       members.Add (o.OperatorMethodBuilder);
+                               }
+                       }
+
+                       if (properties != null) {
+                               int len = properties.Count;
+                               for (int i = 0; i < len; i++) {
+                                       Property p = (Property) properties [i];
+
+                                       if (p.GetBuilder != null)
+                                               members.Add (p.GetBuilder);
+                                       if (p.SetBuilder != null)
+                                               members.Add (p.SetBuilder);
+                               }
+                       }
+                               
+                       if (indexers != null) {
+                               int len = indexers.Count;
+                               for (int i = 0; i < len; i++) {
+                                       Indexer ix = (Indexer) indexers [i];
+
+                                       if (ix.GetBuilder != null)
+                                               members.Add (ix.GetBuilder);
+                                       if (ix.SetBuilder != null)
+                                               members.Add (ix.SetBuilder);
+                               }
+                       }
+
+                       if (events != null) {
+                               int len = events.Count;
+                               for (int i = 0; i < len; i++) {
+                                       Event e = (Event) events [i];
+
+                                       if (e.AddBuilder != null)
+                                               members.Add (e.AddBuilder);
+                                       if (e.RemoveBuilder != null)
+                                               members.Add (e.RemoveBuilder);
+                               }
+                       }
+
+                       MethodInfo[] retMethods = new MethodInfo [members.Count];
+                       members.CopyTo (retMethods, 0);
+                       return retMethods;
+               }
+               
+               // Indicated whether container has StructLayout attribute set Explicit
+               public virtual bool HasExplicitLayout {
+                       get {
+                               return false;
+                       }
+               }
+               
+               /// <summary>
+               ///   This method returns the members of this type just like Type.FindMembers would
+               ///   Only, we need to use this for types which are _being_ defined because MS' 
+               ///   implementation can't take care of that.
+               /// </summary>
+               //
+               // FIXME: return an empty static array instead of null, that cleans up
+               // some code and is consistent with some coding conventions I just found
+               // out existed ;-)
+               //
+               //
+               // Notice that in various cases we check if our field is non-null,
+               // something that would normally mean that there was a bug elsewhere.
+               //
+               // The problem happens while we are defining p-invoke methods, as those
+               // will trigger a FindMembers, but this happens before things are defined
+               //
+               // Since the whole process is a no-op, it is fine to check for null here.
+               //
+               public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
+                                                       MemberFilter filter, object criteria)
+               {
+                       ArrayList members = null;
+
+                       int modflags = 0;
+                       if ((bf & BindingFlags.Public) != 0)
+                               modflags |= Modifiers.PUBLIC | Modifiers.PROTECTED |
+                                       Modifiers.INTERNAL;
+                       if ((bf & BindingFlags.NonPublic) != 0)
+                               modflags |= Modifiers.PRIVATE;
+
+                       int static_mask = 0, static_flags = 0;
+                       switch (bf & (BindingFlags.Static | BindingFlags.Instance)) {
+                       case BindingFlags.Static:
+                               static_mask = static_flags = Modifiers.STATIC;
+                               break;
+
+                       case BindingFlags.Instance:
+                               static_mask = Modifiers.STATIC;
+                               static_flags = 0;
+                               break;
+
+                       default:
+                               static_mask = static_flags = 0;
+                               break;
+                       }
+
+                       Timer.StartTimer (TimerType.TcFindMembers);
+
+                       if (filter == null)
+                               filter = accepting_filter; 
+
+                       if ((mt & MemberTypes.Field) != 0) {
+                               if (fields != null) {
+                                       int len = fields.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Field f = (Field) fields [i];
+                                               
+                                               if ((f.ModFlags & modflags) == 0)
+                                                       continue;
+                                               if ((f.ModFlags & static_mask) != static_flags)
+                                                       continue;
+
+                                               FieldBuilder fb = f.FieldBuilder;
+                                               if (fb != null && filter (fb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (fb);
+                                       }
+                               }
+                               }
+
+                               if (constants != null) {
+                                       int len = constants.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Const con = (Const) constants [i];
+                                               
+                                               if ((con.ModFlags & modflags) == 0)
+                                                       continue;
+                                               if ((con.ModFlags & static_mask) != static_flags)
+                                                       continue;
+
+                                               FieldBuilder fb = con.FieldBuilder;
+                                               if (fb != null && filter (fb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (fb);
+                                       }
+                               }
+                       }
+                       }
+
+                       if ((mt & MemberTypes.Method) != 0) {
+                               if (methods != null) {
+                                       int len = methods.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Method m = (Method) methods [i];
+                                               
+                                               if ((m.ModFlags & modflags) == 0)
+                                                       continue;
+                                               if ((m.ModFlags & static_mask) != static_flags)
+                                                       continue;
+                                               
+                                               MethodBuilder mb = m.MethodBuilder;
+
+                                               if (mb != null && filter (mb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (mb);
+                                       }
+                               }
+                               }
+
+                               if (operators != null) {
+                                       int len = operators.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Operator o = (Operator) operators [i];
+
+                                               if ((o.ModFlags & modflags) == 0)
+                                                       continue;
+                                               if ((o.ModFlags & static_mask) != static_flags)
+                                                       continue;
+                                               
+                                               MethodBuilder ob = o.OperatorMethodBuilder;
+                                               if (ob != null && filter (ob, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (ob);
+                                       }
+                               }
+                               }
+
+                               if (properties != null) {
+                                       int len = properties.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Property p = (Property) properties [i];
+
+                                               if ((p.ModFlags & modflags) == 0)
+                                                       continue;
+                                               if ((p.ModFlags & static_mask) != static_flags)
+                                                       continue;
+                                               
+                                               MethodBuilder b;
+
+                                               b = p.GetBuilder;
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (b);
+                                               }
+
+                                               b = p.SetBuilder;
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (b);
+                                       }
+                               }
+                               }
+                               
+                               if (indexers != null) {
+                                       int len = indexers.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Indexer ix = (Indexer) indexers [i];
+                               
+                                               if ((ix.ModFlags & modflags) == 0)
+                                                       continue;
+                                               if ((ix.ModFlags & static_mask) != static_flags)
+                                                       continue;
+                                               
+                                               MethodBuilder b;
+
+                                               b = ix.GetBuilder;
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (b);
+                                               }
+
+                                               b = ix.SetBuilder;
+                                               if (b != null && filter (b, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (b);
+                                       }
+                               }
+                       }
+                       }
+
+                       if ((mt & MemberTypes.Event) != 0) {
+                               if (events != null) {
+                                       int len = events.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Event e = (Event) events [i];
+                                               
+                                               if ((e.ModFlags & modflags) == 0)
+                                                       continue;
+                                               if ((e.ModFlags & static_mask) != static_flags)
+                                                       continue;
+
+                                               MemberInfo eb = e.EventBuilder;
+                                               if (eb != null && filter (eb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (e.EventBuilder);
+                                       }
+                       }
+                               }
+                       }
+                       
+                       if ((mt & MemberTypes.Property) != 0){
+                               if (properties != null) {
+                                       int len = properties.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Property p = (Property) properties [i];
+                                               
+                                               if ((p.ModFlags & modflags) == 0)
+                                                       continue;
+                                               if ((p.ModFlags & static_mask) != static_flags)
+                                                       continue;
+
+                                               MemberInfo pb = p.PropertyBuilder;
+                                               if (pb != null && filter (pb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (p.PropertyBuilder);
+                                               }
+                                       }
+                               }
+
+                               if (indexers != null) {
+                                       int len = indexers.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Indexer ix = (Indexer) indexers [i];
+
+                                               if ((ix.ModFlags & modflags) == 0)
+                                                       continue;
+                                               if ((ix.ModFlags & static_mask) != static_flags)
+                                                       continue;
+
+                                               MemberInfo ib = ix.PropertyBuilder;
+                                               if (ib != null && filter (ib, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (ix.PropertyBuilder);
+                                               }
+                                       }
+                       }
+                       }
+                       
+                       if ((mt & MemberTypes.NestedType) != 0) {
+                               if (types != null) {
+                                       int len = types.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               TypeContainer t = (TypeContainer) types [i];
+                                               
+                                               if ((t.ModFlags & modflags) == 0)
+                                                       continue;
+
+                                               TypeBuilder tb = t.TypeBuilder;
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                               members.Add (tb);
+                                       }
+                               }
+                               }
+
+                               if (enums != null) {
+                                       int len = enums.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Enum en = (Enum) enums [i];
+
+                                               if ((en.ModFlags & modflags) == 0)
+                                                       continue;
+
+                                               TypeBuilder tb = en.TypeBuilder;
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (tb);
+                                       }
+                               }
+                               }
+                               
+                               if (delegates != null) {
+                                       int len = delegates.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Delegate d = (Delegate) delegates [i];
+                               
+                                               if ((d.ModFlags & modflags) == 0)
+                                                       continue;
+
+                                               TypeBuilder tb = d.TypeBuilder;
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (tb);
+                                       }
+                               }
+                               }
+
+                               if (interfaces != null) {
+                                       int len = interfaces.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               TypeContainer iface = (TypeContainer) interfaces [i];
+
+                                               if ((iface.ModFlags & modflags) == 0)
+                                                       continue;
+
+                                               TypeBuilder tb = iface.TypeBuilder;
+                                               if (tb != null && (filter (tb, criteria) == true)) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                       members.Add (tb);
+                                       }
+                               }
+                       }
+                       }
+
+                       if ((mt & MemberTypes.Constructor) != 0){
+                               if (((bf & BindingFlags.Instance) != 0) && (instance_constructors != null)){
+                                       int len = instance_constructors.Count;
+                                       for (int i = 0; i < len; i++) {
+                                               Constructor c = (Constructor) instance_constructors [i];
+                                               
+                                               ConstructorBuilder cb = c.ConstructorBuilder;
+                                               if (cb != null && filter (cb, criteria) == true) {
+                                                       if (members == null)
+                                                               members = new ArrayList ();
+                                                       
+                                                               members.Add (cb);
+                                       }
+                               }
+                               }
+
+                               if (((bf & BindingFlags.Static) != 0) && (default_static_constructor != null)){
+                                       ConstructorBuilder cb =
+                                               default_static_constructor.ConstructorBuilder;
+                                       
+                                       if (cb != null && filter (cb, criteria) == true) {
+                                               if (members == null)
+                                                       members = new ArrayList ();
+                                               
+                                               members.Add (cb);
+                               }
+                       }
+                       }
+
+                       //
+                       // Lookup members in parent if requested.
+                       //
+                       if ((bf & BindingFlags.DeclaredOnly) == 0) {
+                               if (TypeBuilder.BaseType != null) {
+                               MemberList list = FindMembers (TypeBuilder.BaseType, mt, bf, filter, criteria);
+                               if (list.Count > 0) {
+                                       if (members == null)
+                                               members = new ArrayList ();
+                                       
+                               members.AddRange (list);
+                       }
+                       }
+                               
+                       }
+
+                       Timer.StopTimer (TimerType.TcFindMembers);
+
+                       if (members == null)
+                               return MemberList.Empty;
+                       else
+                       return new MemberList (members);
+               }
+
+               public override MemberCache MemberCache {
+                       get {
+                               return member_cache;
+                       }
+               }
+
+               public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
+                                                     MemberFilter filter, object criteria)
+               {
+                       DeclSpace ds = TypeManager.LookupDeclSpace (t);
+
+                       if (ds != null)
+                               return ds.FindMembers (mt, bf, filter, criteria);
+                       else
+                               return new MemberList (t.FindMembers (mt, bf, filter, criteria));
+               }
+
+               //
+               // FindMethods will look for methods not only in the type `t', but in
+               // any interfaces implemented by the type.
+               //
+               public static MethodInfo [] FindMethods (Type t, BindingFlags bf,
+                                                        MemberFilter filter, object criteria)
+               {
+                       return null;
+               }
+
+               /// <summary>
+               ///   Emits the values for the constants
+               /// </summary>
+               public void EmitConstants ()
+               {
+                       if (constants != null)
+                               foreach (Const con in constants)
+                                       con.Emit ();
+                       return;
+               }
+
+               protected virtual void VerifyMembers (EmitContext ec)
+               {
+                       //
+                       // Check for internal or private fields that were never assigned
+                       //
+                       if (RootContext.WarningLevel >= 3) {
+                               if (fields != null){
+                                       foreach (Field f in fields) {
+                                               if ((f.ModFlags & Modifiers.Accessibility) != Modifiers.PRIVATE)
+                                                       continue;
+                                               
+                                               if ((f.status & Field.Status.USED) == 0){
+                                                       Report.Warning (169, f.Location, "The private field '{0}' is never used", f.GetSignatureForError ());
+                                                       continue;
+                                               }
+                                               
+                                               //
+                                               // Only report 649 on level 4
+                                               //
+                                               if (RootContext.WarningLevel < 4)
+                                                       continue;
+                                               
+                                               if ((f.status & Field.Status.ASSIGNED) != 0)
+                                                       continue;
+                                               
+                                               Report.Warning (649, f.Location, "Field '{0}' is never assigned to, and will always have its default value '{1}'", f.GetSignatureForError (), "");
+                                       }
+                               }
+                       }
+               }
+
+               /// <summary>
+               ///   Emits the code, this step is performed after all
+               ///   the types, enumerations, constructors
+               /// </summary>
+               public void EmitType ()
+               {
+                       if (OptAttributes != null)
+                               OptAttributes.Emit (ec, this);
+
+                       Emit ();
+
+                       if (instance_constructors != null) {
+                               if (TypeBuilder.IsSubclassOf (TypeManager.attribute_type) && RootContext.VerifyClsCompliance && IsClsCompliaceRequired (this)) {
+                                       bool has_compliant_args = false;
+
+                                       foreach (Constructor c in instance_constructors) {
+                                               c.Emit ();
+
+                                               if (has_compliant_args)
+                                                       continue;
+
+                                               has_compliant_args = c.HasCompliantArgs;
+                                       }
+                                       if (!has_compliant_args)
+                                               Report.Error (3015, Location, "'{0}' has no accessible constructors which use only CLS-compliant types", GetSignatureForError ());
+                               } else {
+                               foreach (Constructor c in instance_constructors)
+                                               c.Emit ();
+                               }
+                       }
+
+                       EmitConstants ();
+
+                       if (default_static_constructor != null)
+                               default_static_constructor.Emit ();
+                       
+                       if (methods != null)
+                               foreach (Method m in methods)
+                                       m.Emit ();
+
+                       if (operators != null)
+                               foreach (Operator o in operators)
+                                       o.Emit ();
+
+                       if (properties != null)
+                               foreach (Property p in properties)
+                                       p.Emit ();
+
+                       if (indexers != null){
+                               indexers.Emit ();
+                       }
+                       
+                       if (fields != null)
+                               foreach (Field f in fields)
+                                       f.Emit ();
+
+                       if (events != null){
+                               foreach (Event e in Events)
+                                       e.Emit ();
+                       }
+
+                       if (delegates != null) {
+                               foreach (Delegate d in Delegates) {
+                                       d.Emit ();
+                               }
+                       }
+
+                       if (enums != null) {
+                               foreach (Enum e in enums) {
+                                       e.Emit ();
+                               }
+                       }
+
+                       if (parts != null) {
+                               foreach (ClassPart part in parts)
+                                       part.EmitType ();
+                       }
+
+                       if ((Pending != null) && !(this is ClassPart))
+                               if (Pending.VerifyPendingMethods ())
+                                       return;
+
+                       VerifyMembers (ec);
+
+                       if (iterators != null)
+                               foreach (Iterator iterator in iterators)
+                                       iterator.EmitType ();
+                       
+//                     if (types != null)
+//                             foreach (TypeContainer tc in types)
+//                                     tc.Emit ();
+               }
+               
+               public override void CloseType ()
+               {
+                       if ((caching_flags & Flags.CloseTypeCreated) != 0)
+                               return;
+
+                       try {
+                               caching_flags |= Flags.CloseTypeCreated;
+                                       TypeBuilder.CreateType ();
+                       } catch (TypeLoadException){
+                               //
+                               // This is fine, the code still created the type
+                               //
+//                             Report.Warning (-20, "Exception while creating class: " + TypeBuilder.Name);
+//                             Console.WriteLine (e.Message);
+                       } catch {
+                               Console.WriteLine ("In type: " + Name);
+                               throw;
+                       }
+                       
+                       if (Enums != null)
+                               foreach (Enum en in Enums)
+                                       en.CloseType ();
+
+                       if (Types != null){
+                               foreach (TypeContainer tc in Types)
+                                       if (tc.Kind == Kind.Struct)
+                                               tc.CloseType ();
+
+                               foreach (TypeContainer tc in Types)
+                                       if (tc.Kind != Kind.Struct)
+                                               tc.CloseType ();
+                       }
+
+                       if (Delegates != null)
+                               foreach (Delegate d in Delegates)
+                                       d.CloseType ();
+
+                       if (Iterators != null)
+                               foreach (Iterator i in Iterators)
+                                       i.CloseType ();
+                       
+                       types = null;
+                       properties = null;
+                       enums = null;
+                       delegates = null;
+                       fields = null;
+                       initialized_fields = null;
+                       initialized_static_fields = null;
+                       constants = null;
+                       interfaces = null;
+                       methods = null;
+                       events = null;
+                       indexers = null;
+                       operators = null;
+                       iterators = null;
+                       ec = null;
+                       default_constructor = null;
+                       default_static_constructor = null;
+                       type_bases = null;
+                       OptAttributes = null;
+                       ifaces = null;
+                       parent_cache = null;
+                       member_cache = null;
+               }
+
+               // TODO: make it obsolete and use GetSignatureForError
+               public string MakeName (string n)
+               {
+                       return "`" + Name + "." + n + "'";
+               }
+
+               //
+               // Performs the validation on a Method's modifiers (properties have
+               // the same properties).
+               //
+               public bool MethodModifiersValid (int flags, string n, Location loc)
+               {
+                       const int vao = (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE);
+                       const int va = (Modifiers.VIRTUAL | Modifiers.ABSTRACT);
+                       const int nv = (Modifiers.NEW | Modifiers.VIRTUAL);
+                       bool ok = true;
+                       
+                       //
+                       // At most one of static, virtual or override
+                       //
+                       if ((flags & Modifiers.STATIC) != 0){
+                               if ((flags & vao) != 0){
+                                       Report.Error (
+                                               112, loc, "static method " + MakeName (n) + "can not be marked " +
+                                               "as virtual, abstract or override");
+                                       ok = false;
+                               }
+                       }
+
+                       if (Kind == Kind.Struct){
+                               if ((flags & va) != 0){
+                                       Modifiers.Error_InvalidModifier (loc, "virtual or abstract");
+                                       ok = false;
+                               }
+                       }
+
+                       if ((flags & Modifiers.OVERRIDE) != 0 && (flags & nv) != 0){
+                               Report.Error (
+                                       113, loc, MakeName (n) +
+                                       " marked as override cannot be marked as new or virtual");
+                               ok = false;
+                       }
+
+                       //
+                       // If the declaration includes the abstract modifier, then the
+                       // declaration does not include static, virtual or extern
+                       //
+                       if ((flags & Modifiers.ABSTRACT) != 0){
+                               if ((flags & Modifiers.EXTERN) != 0){
+                                       Report.Error (
+                                               180, loc, MakeName (n) + " can not be both abstract and extern");
+                                       ok = false;
+                               }
+
+                               if ((flags & Modifiers.VIRTUAL) != 0){
+                                       Report.Error (
+                                               503, loc, MakeName (n) + " can not be both abstract and virtual");
+                                       ok = false;
+                               }
+
+                               if ((ModFlags & Modifiers.ABSTRACT) == 0){
+                                       Report.Error (
+                                               513, loc, MakeName (n) +
+                                               " is abstract but its container class is not");
+                                       ok = false;
+
+                               }
+                       }
+
+                       if ((flags & Modifiers.PRIVATE) != 0){
+                               if ((flags & vao) != 0){
+                                       Report.Error (
+                                               621, loc, MakeName (n) +
+                                               " virtual or abstract members can not be private");
+                                       ok = false;
+                               }
+                       }
+
+                       if ((flags & Modifiers.SEALED) != 0){
+                               if ((flags & Modifiers.OVERRIDE) == 0){
+                                       Report.Error (
+                                               238, loc, MakeName (n) +
+                                               " cannot be sealed because it is not an override");
+                                       ok = false;
+                               }
+                       }
+
+                       return ok;
+               }
+
+               public bool UserDefinedStaticConstructor {
+                       get {
+                               return default_static_constructor != null;
+                       }
+               }
+
+               public Constructor DefaultStaticConstructor {
+                       get { return default_static_constructor; }
+               }
+
+               protected override bool VerifyClsCompliance (DeclSpace ds)
+               {
+                       if (!base.VerifyClsCompliance (ds))
+                               return false;
+
+                       VerifyClsName ();
+
+                       if (IsGeneric) {
+                               Report.Error (3024, Location, "'{0}': type parameters are not CLS-compliant",
+                                             GetSignatureForError ());
+                               return false;
+                       }
+
+                       Type base_type = TypeBuilder.BaseType;
+                       if (base_type != null && !AttributeTester.IsClsCompliant (base_type)) {
+                               Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (base_type));
+                       }
+                       return true;
+               }
+
+
+               /// <summary>
+               /// Checks whether container name is CLS Compliant
+               /// </summary>
+               void VerifyClsName ()
+               {
+                       Hashtable parent_members = parent_cache == null ? 
+                               new Hashtable () :
+                               parent_cache.GetPublicMembers ();
+                       Hashtable this_members = new Hashtable ();
+
+                       foreach (DictionaryEntry entry in defined_names) {
+                               MemberCore mc = (MemberCore)entry.Value;
+                               if (!mc.IsClsCompliaceRequired (this))
+                                       continue;
+
+                               string name = (string)entry.Key;
+                               string basename = name.Substring (name.LastIndexOf ('.') + 1);
+
+                               string lcase = basename.ToLower (System.Globalization.CultureInfo.InvariantCulture);
+                               object found = parent_members [lcase];
+                               if (found == null) {
+                                       found = this_members [lcase];
+                                       if (found == null) {
+                                               this_members.Add (lcase, mc);
+                                               continue;
+                                       }
+                               }
+
+                               if ((mc.ModFlags & Modifiers.OVERRIDE) != 0)
+                                       continue;                                       
+
+                               if (found is MemberInfo) {
+                                       if (basename == ((MemberInfo)found).Name)
+                                               continue;
+                                       Report.SymbolRelatedToPreviousError ((MemberInfo)found);
+                               } else {
+                                       Report.SymbolRelatedToPreviousError ((MemberCore) found);
+                               }
+                               Report.Error (3005, mc.Location, "Identifier '{0}' differing only in case is not CLS-compliant", mc.GetSignatureForError ());
+                       }
+               }
+
+
+               /// <summary>
+               ///   Performs checks for an explicit interface implementation.  First it
+               ///   checks whether the `interface_type' is a base inteface implementation.
+               ///   Then it checks whether `name' exists in the interface type.
+               /// </summary>
+               public virtual bool VerifyImplements (Type interface_type, string full,
+                                                     string name, Location loc)
+               {
+                       bool found = false;
+
+                       if (ifaces != null){
+                               foreach (Type t in ifaces){
+                                       if (t == interface_type){
+                                               found = true;
+                                               break;
+                                       }
+                               }
+                       }
+                       
+                       if (!found){
+                               Report.Error (540, "`" + full + "': containing class does not implement interface `" + interface_type.FullName + "'");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               protected override void VerifyObsoleteAttribute()
+               {
+                       CheckUsageOfObsoleteAttribute (TypeBuilder.BaseType);
+
+                       if (ifaces == null)
+                               return;
+
+                       foreach (Type iface in ifaces) {
+                               CheckUsageOfObsoleteAttribute (iface);
+                       }
+               }
+
+               //
+               // IMemberContainer
+               //
+
+               string IMemberContainer.Name {
+                       get {
+                               return Name;
+                       }
+               }
+
+               Type IMemberContainer.Type {
+                       get {
+                               return TypeBuilder;
+                       }
+               }
+
+               MemberCache IMemberContainer.MemberCache {
+                       get {
+                               return member_cache;
+                       }
+               }
+
+               bool IMemberContainer.IsInterface {
+                       get {
+                               return Kind == Kind.Interface;
+                       }
+               }
+
+               MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
+               {
+                       BindingFlags new_bf = bf | BindingFlags.DeclaredOnly;
+
+                       if (GenericType != null)
+                               return TypeManager.FindMembers (GenericType, mt, new_bf,
+                                                               null, null);
+                       else
+                               return FindMembers (mt, new_bf, null, null);
+               }
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal override void GenerateDocComment (DeclSpace ds)
+               {
+                       DocUtil.GenerateTypeDocComment (this, ds);
+               }
+
+               public override string DocCommentHeader {
+                       get { return "T:"; }
+               }
+
+               public virtual MemberCache ParentCache {
+                       get {
+                               return parent_cache;
+                       }
+               }
+               
+       }
+
+       public class PartialContainer : TypeContainer {
+
+               public readonly Namespace Namespace;
+               public readonly int OriginalModFlags;
+               public readonly int AllowedModifiers;
+               public readonly TypeAttributes DefaultTypeAttributes;
+
+               static PartialContainer Create (NamespaceEntry ns, TypeContainer parent,
+                                               MemberName member_name, int mod_flags, Kind kind,
+                                               Location loc)
+               {
+                       PartialContainer pc;
+                       string full_name = member_name.GetName (true);
+                       DeclSpace ds = (DeclSpace) RootContext.Tree.Decls [full_name];
+                       if (ds != null) {
+                               pc = ds as PartialContainer;
+
+                               if (pc == null) {
+                                       Report.Error (
+                                               260, ds.Location, "Missing partial modifier " +
+                                               "on declaration of type `{0}'; another " +
+                                               "partial implementation of this type exists",
+                                               member_name.GetTypeName());
+
+                                       Report.LocationOfPreviousError (loc);
+                                       return null;
+                               }
+
+                               if (pc.Kind != kind) {
+                                       Report.Error (
+                                               261, loc, "Partial declarations of `{0}' " +
+                                               "must be all classes, all structs or " +
+                                               "all interfaces", member_name.GetTypeName ());
+                                       return null;
+                               }
+
+                               if (pc.OriginalModFlags != mod_flags) {
+                                       Report.Error (
+                                               262, loc, "Partial declarations of `{0}' " +
+                                               "have conflicting accessibility modifiers",
+                                               member_name.GetTypeName ());
+                                       return null;
+                               }
+
+                               return pc;
+                       }
+
+                       pc = new PartialContainer (ns, parent, member_name, mod_flags, kind, loc);
+                       RootContext.Tree.RecordDecl (full_name, pc);
+                       parent.AddType (pc);
+                       pc.Register ();
+                       return pc;
+               }
+
+               public static ClassPart CreatePart (NamespaceEntry ns, TypeContainer parent,
+                                                   MemberName name, int mod, Attributes attrs,
+                                                   Kind kind, Location loc)
+               {
+                       PartialContainer pc = Create (ns, parent, name, mod, kind, loc);
+                       if (pc == null) {
+                               // An error occured; create a dummy container, but don't
+                               // register it.
+                               pc = new PartialContainer (ns, parent, name, mod, kind, loc);
+                       }
+
+                       ClassPart part = new ClassPart (ns, pc, mod, attrs, kind, loc);
+                       pc.AddPart (part);
+                       return part;
+               }
+
+               protected PartialContainer (NamespaceEntry ns, TypeContainer parent,
+                                           MemberName name, int mod, Kind kind, Location l)
+                       : base (ns, parent, name, null, kind, l)
+               {
+                       this.Namespace = ns.NS;
+
+                       switch (kind) {
+                       case Kind.Class:
+                               AllowedModifiers = Class.AllowedModifiers;
+                               DefaultTypeAttributes = Class.DefaultTypeAttributes;
+                               break;
+
+                       case Kind.Struct:
+                               AllowedModifiers = Struct.AllowedModifiers;
+                               DefaultTypeAttributes = Struct.DefaultTypeAttributes;
+                               break;
+
+                       case Kind.Interface:
+                               AllowedModifiers = Interface.AllowedModifiers;
+                               DefaultTypeAttributes = Interface.DefaultTypeAttributes;
+                               break;
+
+                       default:
+                               throw new InvalidOperationException ();
+                       }
+
+                       int accmods;
+                       if (parent.Parent == null)
+                               accmods = Modifiers.INTERNAL;
+                       else
+                               accmods = Modifiers.PRIVATE;
+
+                       this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
+                       this.OriginalModFlags = mod;
+               }
+
+               public override void Register ()
+               {
+                       if (Kind == Kind.Interface)
+                               Parent.AddInterface (this);
+                       else if (Kind == Kind.Class || Kind == Kind.Struct)
+                               Parent.AddClassOrStruct (this);
+                       else
+                               throw new InvalidOperationException ();
+               }
+
+               public override PendingImplementation GetPendingImplementations ()
+               {
+                       return PendingImplementation.GetPendingImplementations (this);
+               }
+
+               public ClassPart AddPart (NamespaceEntry ns, int mod, Attributes attrs,
+                                         Location l)
+               {
+                       ClassPart part = new ClassPart (ns, this, mod, attrs, Kind, l);
+                       AddPart (part);
+                       return part;
+               }
+
+               public override TypeAttributes TypeAttr {
+                       get {
+                               return base.TypeAttr | DefaultTypeAttributes;
+                       }
+               }
+       }
+
+       public class ClassPart : TypeContainer, IMemberContainer {
+               public readonly PartialContainer PartialContainer;
+               public readonly bool IsPartial;
+
+               public ClassPart (NamespaceEntry ns, PartialContainer parent,
+                                 int mod, Attributes attrs, Kind kind, Location l)
+                       : base (ns, parent.Parent, parent.MemberName, attrs, kind, l)
+               {
+                       this.PartialContainer = parent;
+                       this.IsPartial = true;
+
+                       int accmods;
+                       if (parent.Parent == null)
+                               accmods = Modifiers.INTERNAL;
+                       else
+                               accmods = Modifiers.PRIVATE;
+
+                       this.ModFlags = Modifiers.Check (
+                               parent.AllowedModifiers, mod, accmods, l);
+               }
+
+               public override void Register ()
+               {
+               }
+
+               public override PendingImplementation GetPendingImplementations ()
+               {
+                       return PartialContainer.Pending;
+               }
+
+               public override bool VerifyImplements (Type interface_type, string full,
+                                                      string name, Location loc)
+               {
+                       return PartialContainer.VerifyImplements (
+                               interface_type, full, name, loc);
+               }
+
+               public override MemberCache ParentCache {
+                       get {
+                               return PartialContainer.ParentCache;
+                       }
+               }
+       }
+
+       public abstract class ClassOrStruct : TypeContainer {
+               bool hasExplicitLayout = false;
+               ListDictionary declarative_security;
+
+               public ClassOrStruct (NamespaceEntry ns, TypeContainer parent,
+                                     MemberName name, Attributes attrs, Kind kind,
+                                     Location l)
+                       : base (ns, parent, name, attrs, kind, l)
+               {
+               }
+
+               public override PendingImplementation GetPendingImplementations ()
+               {
+                       return PendingImplementation.GetPendingImplementations (this);
+               }
+
+               public override bool HasExplicitLayout {
+                       get {
+                               return hasExplicitLayout;
+                               }
+                       }
+
+               protected override void VerifyMembers (EmitContext ec)
+               {
+                       base.VerifyMembers (ec);
+
+                       if ((events != null) && (RootContext.WarningLevel >= 3)) {
+                               foreach (Event e in events){
+                                       if (e.status == 0)
+                                               Report.Warning (67, e.Location, "The event '{0}' is never used", e.GetSignatureForError ());
+                               }
+                       }
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
+                               if (declarative_security == null)
+                                       declarative_security = new ListDictionary ();
+
+                               a.ExtractSecurityPermissionSet (declarative_security);
+                               return;
+                       }
+
+                       if (a.Type == TypeManager.struct_layout_attribute_type
+                           && (LayoutKind) a.GetPositionalValue (0) == LayoutKind.Explicit)
+                               hasExplicitLayout = true;
+
+                       base.ApplyAttributeBuilder (a, cb);
+               }
+
+               public override void Emit()
+               {
+                       base.Emit ();
+
+                       if (declarative_security != null) {
+                               foreach (DictionaryEntry de in declarative_security) {
+                                       TypeBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
+                               }
+                       }
+               }
+
+               public override void Register ()
+               {
+                       Parent.AddClassOrStruct (this);
+               }
+       }
+
+       /// <summary>
+       /// Class handles static classes declaration
+       /// </summary>
+       public sealed class StaticClass: Class {
+               public StaticClass (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
+                                   Attributes attrs, Location l)
+                       : base (ns, parent, name, mod & ~Modifiers.STATIC, attrs, l)
+               {
+                       if (RootContext.Version == LanguageVersion.ISO_1) {
+                               Report.FeatureIsNotStandardized (l, "static classes");
+                               Environment.Exit (1);
+                       }
+               }
+
+               protected override void DefineContainerMembers (MemberCoreArrayList list)
+               {
+                       if (list == null)
+                               return;
+
+                       foreach (MemberCore m in list) {
+                               if (m is Operator) {
+                                       Report.Error (715, m.Location, "'{0}': static classes cannot contain user-defined operators", m.GetSignatureForError (this));
+                                       continue;
+                               }
+
+                               if ((m.ModFlags & Modifiers.STATIC) != 0)
+                                       continue;
+
+                               if (m is Constructor) {
+                                       Report.Error (710, m.Location, "'{0}': Static classes cannot have instance constructors", GetSignatureForError ());
+                                       continue;
+                               }
+
+                               if (m is Destructor) {
+                                       Report.Error (711, m.Location, "'{0}': Static class cannot contain destructor", GetSignatureForError ());
+                                       continue;
+                               }
+                               Report.Error (708, m.Location, "'{0}': cannot declare instance members in a static class", m.GetSignatureForError (this));
+                       }
+
+                       base.DefineContainerMembers (list);
+               }
+
+               public override TypeBuilder DefineType()
+               {
+                       TypeBuilder tb = base.DefineType ();
+                       if (tb == null)
+                               return null;
+
+                       if ((ptype != null) && (ptype != TypeManager.object_type)) {
+                               Report.Error (
+                                       713, Location,
+                                       "Static class '{0}' cannot derive from type '{1}'. " +
+                                       "Static classes must derive from object",
+                                       GetSignatureForError (), ptype);
+                               return null;
+                       }
+
+                       if (ifaces != null) {
+                               foreach (Type t in ifaces)
+                                       Report.SymbolRelatedToPreviousError (t);
+                               Report.Error (
+                                       714, Location,
+                                       "'{0}': static classes cannot implement interfaces",
+                                       GetSignatureForError ());
+                       }
+                       return tb;
+               }
+
+               public override TypeAttributes TypeAttr {
+                       get {
+                               return base.TypeAttr | TypeAttributes.Abstract | TypeAttributes.Sealed;
+                       }
+               }
+       }
+
+       public class Class : ClassOrStruct {
+               // <summary>
+               //   Modifiers allowed in a class declaration
+               // </summary>
+               public const int AllowedModifiers =
+                       Modifiers.NEW |
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE |
+                       Modifiers.ABSTRACT |
+                       Modifiers.SEALED |
+                       Modifiers.UNSAFE;
+
+               // Information in the case we are an attribute type
+               AttributeUsageAttribute attribute_usage;
+
+               public Class (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
+                             Attributes attrs, Location l)
+                       : base (ns, parent, name, attrs, Kind.Class, l)
+               {
+                       int accmods;
+
+                       if (parent.Parent == null)
+                               accmods = Modifiers.INTERNAL;
+                       else
+                               accmods = Modifiers.PRIVATE;
+
+                       this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
+                       if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.SEALED)) == (Modifiers.ABSTRACT | Modifiers.SEALED)) {
+                               Report.Error (502, Location, "'{0}' cannot be both abstract and sealed", GetSignatureForError ());
+                       }
+
+                       attribute_usage = new AttributeUsageAttribute (AttributeTargets.All);
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Class;
+                       }
+               }
+
+               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.UsageAttribute != null) {
+                               if (ptype != TypeManager.attribute_type &&
+                                   !ptype.IsSubclassOf (TypeManager.attribute_type) &&
+                                   TypeBuilder.FullName != "System.Attribute") {
+                                       Report.Error (641, a.Location, "Attribute '{0}' is only valid on classes derived from System.Attribute", a.Name);
+                               }
+                               attribute_usage = a.UsageAttribute;
+                       }
+
+                       base.ApplyAttributeBuilder (a, cb);
+               }
+
+               public AttributeUsageAttribute AttributeUsage {
+                       get {
+                               return attribute_usage;
+                       }
+               }
+
+               public const TypeAttributes DefaultTypeAttributes =
+                       TypeAttributes.AutoLayout | TypeAttributes.Class;
+
+               //
+               // FIXME: How do we deal with the user specifying a different
+               // layout?
+               //
+               public override TypeAttributes TypeAttr {
+                       get {
+                               return base.TypeAttr | DefaultTypeAttributes;
+                       }
+               }
+       }
+
+       public class Struct : ClassOrStruct {
+               // <summary>
+               //   Modifiers allowed in a struct declaration
+               // </summary>
+               public const int AllowedModifiers =
+                       Modifiers.NEW       |
+                       Modifiers.PUBLIC    |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL  |
+                       Modifiers.UNSAFE    |
+                       Modifiers.PRIVATE;
+
+               public Struct (NamespaceEntry ns, TypeContainer parent, MemberName name,
+                              int mod, Attributes attrs, Location l)
+                       : base (ns, parent, name, attrs, Kind.Struct, l)
+               {
+                       int accmods;
+                       
+                       if (parent.Parent == null)
+                               accmods = Modifiers.INTERNAL;
+                       else
+                               accmods = Modifiers.PRIVATE;
+                       
+                       this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
+
+                       this.ModFlags |= Modifiers.SEALED;
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Struct;
+                       }
+               }
+
+               public const TypeAttributes DefaultTypeAttributes =
+                       TypeAttributes.SequentialLayout |
+                       TypeAttributes.Sealed |
+                       TypeAttributes.BeforeFieldInit;
+
+               //
+               // FIXME: Allow the user to specify a different set of attributes
+               // in some cases (Sealed for example is mandatory for a class,
+               // but what SequentialLayout can be changed
+               //
+               public override TypeAttributes TypeAttr {
+                       get {
+                               return base.TypeAttr | DefaultTypeAttributes;
+                       }
+               }
+       }
+
+       /// <summary>
+       ///   Interfaces
+       /// </summary>
+       public class Interface : TypeContainer, IMemberContainer {
+               /// <summary>
+               ///   Modifiers allowed in a class declaration
+               /// </summary>
+               public const int AllowedModifiers =
+                       Modifiers.NEW       |
+                       Modifiers.PUBLIC    |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL  |
+                       Modifiers.UNSAFE    |
+                       Modifiers.PRIVATE;
+
+               public Interface (NamespaceEntry ns, TypeContainer parent, MemberName name,
+                                 int mod, Attributes attrs, Location l)
+                       : base (ns, parent, name, attrs, Kind.Interface, l)
+               {
+                       int accmods;
+
+                       if (parent.Parent == null)
+                               accmods = Modifiers.INTERNAL;
+                       else
+                               accmods = Modifiers.PRIVATE;
+
+                       this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
+               }
+
+               public override void Register ()
+               {
+                       Parent.AddInterface (this);
+               }
+
+               public override PendingImplementation GetPendingImplementations ()
+               {
+                       return null;
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Interface;
+                       }
+               }
+
+               public const TypeAttributes DefaultTypeAttributes =
+                                       TypeAttributes.AutoLayout |
+                                       TypeAttributes.Abstract |
+                                       TypeAttributes.Interface;
+
+               public override TypeAttributes TypeAttr {
+                       get {
+                               return base.TypeAttr | DefaultTypeAttributes;
+                       }
+               }
+       }
+
+       public abstract class MethodCore : MemberBase {
+               public readonly Parameters Parameters;
+               public readonly GenericMethod GenericMethod;
+               public readonly DeclSpace ds;
+               protected ToplevelBlock block;
+               
+               //
+               // Parameters, cached for semantic analysis.
+               //
+               protected InternalParameters parameter_info;
+               protected Type [] parameter_types;
+
+               // Whether this is an operator method.
+               public bool IsOperator;
+
+               //
+               // The method we're overriding if this is an override method.
+               //
+               protected MethodInfo parent_method = null;
+
+               static string[] attribute_targets = new string [] { "method", "return" };
+
+               public MethodCore (TypeContainer parent, GenericMethod generic,
+                                  Expression type, int mod, int allowed_mod, bool is_iface,
+                                  MemberName name, Attributes attrs, Parameters parameters,
+                                  Location loc)
+                       : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE, name,
+                               attrs, loc)
+               {
+                       Parameters = parameters;
+                       IsInterface = is_iface;
+                       this.GenericMethod = generic;
+
+                       if (generic != null)
+                               ds = generic;
+                       else
+                               ds = parent;
+               }
+               
+               //
+               //  Returns the System.Type array for the parameters of this method
+               //
+               public Type [] ParameterTypes {
+                       get {
+                               return parameter_types;
+                       }
+               }
+
+               public InternalParameters ParameterInfo
+               {
+                       get {
+                               return parameter_info;
+                       }
+               }
+               
+               public ToplevelBlock Block {
+                       get {
+                               return block;
+                       }
+
+                       set {
+                               block = value;
+                       }
+               }
+
+               protected override bool CheckBase ()
+               {
+                       if (!base.CheckBase ())
+                               return false;
+                       
+                       // Check whether arguments were correct.
+                       if (!DoDefineParameters ())
+                               return false;
+
+                       if ((caching_flags & Flags.TestMethodDuplication) != 0 && !CheckForDuplications ())
+                               return false;
+
+                       if (IsExplicitImpl)
+                               return true;
+
+                       // Is null for System.Object while compiling corlib and base interfaces
+                       if (Parent.ParentCache == null) {
+                               if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
+                                       Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
+                               }
+                               return true;
+                       }
+
+                       Type parent_ret_type = null;
+                       parent_method = FindOutParentMethod (Parent, ref parent_ret_type);
+
+                       // method is override
+                       if (parent_method != null) {
+
+                               if (!CheckMethodAgainstBase ())
+                                       return false;
+
+                               if ((ModFlags & Modifiers.NEW) == 0) {
+                                       if (!MemberType.Equals (TypeManager.TypeToCoreType (parent_ret_type))) {
+                                               Report.SymbolRelatedToPreviousError (parent_method);
+                                               Report.Error (508, Location, GetSignatureForError (Parent) + ": cannot " +
+                                                       "change return type when overriding inherited member");
+                                               return false;
+                                       }
+                               } else {
+                                       if (parent_method.IsAbstract && !IsInterface) {
+                                               Report.SymbolRelatedToPreviousError (parent_method);
+                                               Report.Error (533, Location, "'{0}' hides inherited abstract member", GetSignatureForError (Parent));
+                                               return false;
+                                       }
+                               }
+
+                               if (parent_method.IsSpecialName && !(this is PropertyBase)) {
+                                       Report.Error (561, Location, "'{0}': cannot override '{1}' because it is a special compiler-generated method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (parent_method));
+                                       return false;
+                               }
+
+                               if (RootContext.WarningLevel > 2) {
+                                       if (Name == "Equals" && parameter_types.Length == 1 && parameter_types [0] == TypeManager.object_type)
+                                               Parent.Methods.HasEquals = true;
+                                       else if (Name == "GetHashCode" && parameter_types.Length == 0)
+                                               Parent.Methods.HasGetHashCode = true;
+                               }
+
+                               ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (parent_method);
+                               if (oa != null) {
+                                       EmitContext ec = new EmitContext (this.Parent, this.Parent, Location, null, null, ModFlags, false);
+                                       if (OptAttributes == null || !OptAttributes.Contains (TypeManager.obsolete_attribute_type, ec)) {
+                                               Report.SymbolRelatedToPreviousError (parent_method);
+                                               Report.Warning (672, 1, Location, "Member '{0}' overrides obsolete member. Add the Obsolete attribute to '{0}'", GetSignatureForError (Parent));
+                                       }
+                               }
+                               return true;
+                       }
+
+                       MemberInfo conflict_symbol = Parent.FindMemberWithSameName (Name, !(this is Property));
+                       if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+                               if (conflict_symbol != null) {
+                                       Report.SymbolRelatedToPreviousError (conflict_symbol);
+                                       if (this is PropertyBase)
+                                               Report.Error (544, Location, "'{0}': cannot override because '{1}' is not a property", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
+                                       else
+                                               Report.Error (505, Location, "'{0}': cannot override because '{1}' is not a method", GetSignatureForError (Parent), TypeManager.GetFullNameSignature (conflict_symbol));
+                               } else
+                               Report.Error (115, Location, "'{0}': no suitable methods found to override", GetSignatureForError (Parent));
+                               return false;
+                       }
+
+                       if (conflict_symbol == null) {
+                               if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
+                                       Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
+                               }
+                               return true;
+                       }
+
+                       if ((ModFlags & Modifiers.NEW) == 0) {
+                               if (this is Method && conflict_symbol is MethodBase)
+                                       return true;
+
+                               Report.SymbolRelatedToPreviousError (conflict_symbol);
+                               Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
+                       }
+
+                       return true;
+               }
+
+
+               //
+               // Performs various checks on the MethodInfo `mb' regarding the modifier flags
+               // that have been defined.
+               //
+               // `name' is the user visible name for reporting errors (this is used to
+               // provide the right name regarding method names and properties)
+               //
+               bool CheckMethodAgainstBase ()
+               {
+                       bool ok = true;
+
+                       // TODO: replace with GetSignatureForError 
+                       string name = parent_method.DeclaringType.Name + "." + parent_method.Name;
+
+                       if ((ModFlags & Modifiers.OVERRIDE) != 0){
+                               if (!(parent_method.IsAbstract || parent_method.IsVirtual)){
+                                       Report.Error (
+                                               506, Location, Parent.MakeName (Name) +
+                                               ": cannot override inherited member `" +
+                                               name + "' because it is not " +
+                                               "virtual, abstract or override");
+                                       ok = false;
+                               }
+                               
+                               // Now we check that the overriden method is not final
+                               
+                               if (parent_method.IsFinal) {
+                                       // This happens when implementing interface methods.
+                                       if (parent_method.IsHideBySig && parent_method.IsVirtual) {
+                                               Report.Error (
+                                                       506, Location, Parent.MakeName (Name) +
+                                                       ": cannot override inherited member `" +
+                                                       name + "' because it is not " +
+                                                       "virtual, abstract or override");
+                                       } else
+                                               Report.Error (239, Location, Parent.MakeName (Name) + " : cannot " +
+                                                             "override inherited member `" + name +
+                                                             "' because it is sealed.");
+                                       ok = false;
+                               }
+                               //
+                               // Check that the permissions are not being changed
+                               //
+                               MethodAttributes thisp = flags & MethodAttributes.MemberAccessMask;
+                               MethodAttributes parentp = parent_method.Attributes & MethodAttributes.MemberAccessMask;
+
+                               if (!CheckAccessModifiers (thisp, parentp, parent_method)) {
+                                       Error_CannotChangeAccessModifiers (Parent, parent_method, name);
+                                       ok = false;
+                               }
+                       }
+
+                       if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0 && Name != "Finalize") {
+                               ModFlags |= Modifiers.NEW;
+                               Report.SymbolRelatedToPreviousError (parent_method);
+                               if (!IsInterface && (parent_method.IsVirtual || parent_method.IsAbstract)) {
+                                       if (RootContext.WarningLevel >= 2)
+                                               Report.Warning (114, Location, "'{0}' hides inherited member '{1}'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword", GetSignatureForError (Parent), TypeManager.CSharpSignature (parent_method));
+                               } else
+                                       Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
+                       }
+
+                       return ok;
+               }
+               
+               protected bool CheckAccessModifiers (MethodAttributes thisp, MethodAttributes parentp, MethodInfo base_method)
+               {
+                       if ((parentp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
+                               //
+                               // when overriding protected internal, the method can be declared
+                               // protected internal only within the same assembly
+                               //
+
+                               if ((thisp & MethodAttributes.FamORAssem) == MethodAttributes.FamORAssem){
+                                       if (Parent.TypeBuilder.Assembly != base_method.DeclaringType.Assembly){
+                                               //
+                                               // assemblies differ - report an error
+                                               //
+                                               
+                                               return false;
+                                       } else if (thisp != parentp) {
+                                               //
+                                               // same assembly, but other attributes differ - report an error
+                                               //
+                                               
+                                               return false;
+                                       };
+                               } else if ((thisp & MethodAttributes.Family) != MethodAttributes.Family) {
+                                       //
+                                       // if it's not "protected internal", it must be "protected"
+                                       //
+
+                                       return false;
+                               } else if (Parent.TypeBuilder.Assembly == base_method.DeclaringType.Assembly) {
+                                       //
+                                       // protected within the same assembly - an error
+                                       //
+                                       return false;
+                               } else if ((thisp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem)) != 
+                                          (parentp & ~(MethodAttributes.Family | MethodAttributes.FamORAssem))) {
+                                       //
+                                       // protected ok, but other attributes differ - report an error
+                                       //
+                                       return false;
+                               }
+                               return true;
+                       } else {
+                               return (thisp == parentp);
+                       }
+               }
+               
+               void Error_CannotChangeAccessModifiers (TypeContainer parent, MethodInfo parent_method, string name)
+               {
+                       //
+                       // FIXME: report the old/new permissions?
+                       //
+                       Report.Error (
+                               507, Location, parent.MakeName (Name) +
+                               ": can't change the access modifiers when overriding inherited " +
+                               "member `" + name + "'");
+               }
+
+               protected static string Error722 {
+                       get {
+                               return "'{0}': static types cannot be used as return types";
+                       }
+               }
+
+               /// <summary>
+               /// For custom member duplication search in a container
+               /// </summary>
+               protected abstract bool CheckForDuplications ();
+
+               /// <summary>
+               /// Gets parent method and its return type
+               /// </summary>
+               protected abstract MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type);
+
+               protected virtual bool DoDefineParameters ()
+               {
+                       EmitContext ec = ds.EmitContext;
+                       if (ec == null)
+                               throw new InternalErrorException ("DoDefineParameters invoked too early");
+
+                       bool old_unsafe = ec.InUnsafe;
+                       ec.InUnsafe = InUnsafe;
+                       // Check if arguments were correct
+                       parameter_types = Parameters.GetParameterInfo (ec);
+                       ec.InUnsafe = old_unsafe;
+
+                       if ((parameter_types == null) ||
+                           !CheckParameters (ds, parameter_types))
+                               return false;
+
+                       TypeParameter[] tparam = ds.IsGeneric ? ds.TypeParameters : null;
+                       parameter_info = new InternalParameters (parameter_types, Parameters, tparam);
+
+                       Parameter array_param = Parameters.ArrayParameter;
+                       if ((array_param != null) &&
+                           (!array_param.ParameterType.IsArray ||
+                            (array_param.ParameterType.GetArrayRank () != 1))) {
+                               Report.Error (225, Location, "params parameter has to be a single dimensional array");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               void error_425 (Type old, Type t, string name)
+               {
+                       Report.Error (425, Location,
+                                     "The constraints of type parameter `{0}' " +
+                                     "of method `{1}' must match the constraints for " +
+                                     "type parameter `{2}' of method `{3}'",
+                                     TypeManager.CSharpName (old), Name,
+                                     TypeManager.CSharpName (t), name);
+               }
+
+               protected override bool CheckGenericOverride (MethodInfo method, string name)
+               {
+                       ParameterData pd = Invocation.GetParameterData (method);
+
+                       for (int i = 0; i < ParameterTypes.Length; i++) {
+                               GenericConstraints ogc = pd.GenericConstraints (i);
+                               GenericConstraints gc = ParameterInfo.GenericConstraints (i);
+
+                               if ((gc == null) && (ogc == null))
+                                       continue;
+
+                               Type ot = pd.ParameterType (i);
+                               Type t = ParameterTypes [i];
+
+                               if (!((gc != null) && (ogc != null))) {
+                                       error_425 (ot, t, name);
+                                       return false;
+                               }
+
+                               if ((gc.Attributes != ogc.Attributes) ||
+                                   (gc.HasClassConstraint != ogc.HasClassConstraint)) {
+                                       error_425 (ot, t, name);
+                                       return false;
+                               }
+
+                               if (ogc.HasClassConstraint &&
+                                   !ogc.ClassConstraint.Equals (gc.ClassConstraint)) {
+                                       error_425 (ot, t, name);
+                                       return false;
+                               }
+
+                               Type[] oct = ogc.InterfaceConstraints;
+                               Type[] ct = gc.InterfaceConstraints;
+
+                               if (oct.Length != ct.Length) {
+                                       error_425 (ot, t, name);
+                                       return false;
+                               }
+
+                               for (int j = 0; j < oct.Length; j++)
+                                       if (!oct [j].Equals (ct [j])) {
+                                               error_425 (ot, t, name);
+                                               return false;
+                                       }
+                       }
+
+                       return true;
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+
+               protected override bool VerifyClsCompliance (DeclSpace ds)
+               {
+                       if (!base.VerifyClsCompliance (ds)) {
+                               if ((ModFlags & Modifiers.ABSTRACT) != 0 && IsExposedFromAssembly (ds) && ds.IsClsCompliaceRequired (ds)) {
+                                       Report.Error (3011, Location, "'{0}': only CLS-compliant members can be abstract", GetSignatureForError ());
+                               }
+                               return false;
+                       }
+
+                       if (Parameters.HasArglist) {
+                               Report.Error (3000, Location, "Methods with variable arguments are not CLS-compliant");
+                       }
+
+                       if (!AttributeTester.IsClsCompliant (MemberType)) {
+                               if ((this is Property) || (this is Indexer))
+                                       Report.Error (3003, Location, "Type of `{0}' is not CLS-compliant",
+                                                     GetSignatureForError ());
+                               else
+                                       Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant",
+                                                     GetSignatureForError ());
+                       }
+
+                       AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
+
+                       return true;
+               }
+
+               bool MayUnify (MethodCore first, MethodCore second)
+               {
+                       int a_type_params = 0;
+                       if (first.GenericMethod != null)
+                               a_type_params = first.GenericMethod.CountTypeParameters;
+
+                       int b_type_params = 0;
+                       if (second.GenericMethod != null)
+                               b_type_params = second.GenericMethod.CountTypeParameters;
+
+                       if (a_type_params != b_type_params)
+                               return false;
+
+                       Type[] class_infered, method_infered;
+                       if (Parent.CountTypeParameters > 0)
+                               class_infered = new Type [Parent.CountTypeParameters];
+                       else
+                               class_infered = null;
+
+                       if (a_type_params > 0)
+                               method_infered = new Type [a_type_params];
+                       else
+                               method_infered = null;
+
+                       return TypeManager.MayBecomeEqualGenericInstances (
+                               first.ParameterTypes, second.ParameterTypes, class_infered, method_infered);
+               }
+
+               protected bool IsDuplicateImplementation (MethodCore method)
+               {
+                       if ((method == this) ||
+                           (method.MemberName.GetTypeName () != MemberName.GetTypeName ()))
+                               return false;
+
+                       Type[] param_types = method.ParameterTypes;
+                       if (param_types == null)
+                               return false;
+
+                       if (param_types.Length != ParameterTypes.Length)
+                               return false;
+
+                       bool equal = true;
+                       bool may_unify = MayUnify (this, method);
+
+                       for (int i = 0; i < param_types.Length; i++) {
+                               if (param_types [i] != ParameterTypes [i])
+                                       equal = false;
+                       }
+
+                       // TODO: make operator compatible with MethodCore to avoid this
+                       if (this is Operator && method is Operator) {
+                               if (MemberType != method.MemberType)
+                                       equal = may_unify = false;
+                       }
+
+                       if (equal) {
+                               //
+                               // Try to report 663: method only differs on out/ref
+                               //
+                               ParameterData info = ParameterInfo;
+                               ParameterData other_info = method.ParameterInfo;
+                               for (int i = 0; i < info.Count; i++){
+                                       if (info.ParameterModifier (i) != other_info.ParameterModifier (i)){
+                                               Report.Error (663, Location,
+                                                             "Overload method only differs " +
+                                                             "in parameter modifier");
+                                               return false;
+                                       }
+                               }
+
+                               Report.SymbolRelatedToPreviousError (method);
+                               Report.Error (111, Location, "Type '{0}' already defines a member called '{1}' with the same parameter types", Parent.Name, Name);
+                               return true;
+                       } else if (may_unify) {
+                               Report.Error (408, Location,
+                                             "`{0}' cannot define overload members that " +
+                                             "may unify for some type parameter substitutions",
+                                             Parent.MemberName);
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               //
+               // Returns a string that represents the signature for this 
+               // member which should be used in XML documentation.
+               //
+               public override string GetDocCommentName (DeclSpace ds)
+               {
+                       return DocUtil.GetMethodDocCommentName (this, ds);
+               }
+
+               //
+               // Raised (and passed an XmlElement that contains the comment)
+               // when GenerateDocComment is writing documentation expectedly.
+               //
+               // FIXME: with a few effort, it could be done with XmlReader,
+               // that means removal of DOM use.
+               //
+               internal override void OnGenerateDocComment (DeclSpace ds, XmlElement el)
+               {
+                       DocUtil.OnMethodGenerateDocComment (this, ds, el);
+               }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "M:"; }
+               }
+
+               protected override void VerifyObsoleteAttribute()
+               {
+                       base.VerifyObsoleteAttribute ();
+
+                       if (parameter_types == null)
+                               return;
+
+                       foreach (Type type in parameter_types) {
+                               CheckUsageOfObsoleteAttribute (type);
+                       }
+               }
+       }
+
+       public class SourceMethod : ISourceMethod
+       {
+               TypeContainer container;
+               MethodBase builder;
+
+               protected SourceMethod (TypeContainer container, MethodBase builder,
+                                       ISourceFile file, Location start, Location end)
+               {
+                       this.container = container;
+                       this.builder = builder;
+                       
+                       CodeGen.SymbolWriter.OpenMethod (
+                               file, this, start.Row, 0, end.Row, 0);
+               }
+
+               public string Name {
+                       get { return builder.Name; }
+               }
+
+               public int NamespaceID {
+                       get { return container.NamespaceEntry.SymbolFileID; }
+               }
+
+               public int Token {
+                       get {
+                               if (builder is MethodBuilder)
+                                       return ((MethodBuilder) builder).GetToken ().Token;
+                               else if (builder is ConstructorBuilder)
+                                       return ((ConstructorBuilder) builder).GetToken ().Token;
+                               else
+                                       throw new NotSupportedException ();
+                       }
+               }
+
+               public void CloseMethod ()
+               {
+                       if (CodeGen.SymbolWriter != null)
+                               CodeGen.SymbolWriter.CloseMethod ();
+               }
+
+               public static SourceMethod Create (TypeContainer parent,
+                                                  MethodBase builder, Block block)
+               {
+                       if (CodeGen.SymbolWriter == null)
+                               return null;
+                       if (block == null)
+                               return null;
+
+                       Location start_loc = block.StartLocation;
+                       if (Location.IsNull (start_loc))
+                               return null;
+
+                       Location end_loc = block.EndLocation;
+                       if (Location.IsNull (end_loc))
+                               return null;
+
+                       ISourceFile file = start_loc.SourceFile;
+                       if (file == null)
+                               return null;
+
+                       return new SourceMethod (
+                               parent, builder, file, start_loc, end_loc);
+               }
+       }
+
+       public class Method : MethodCore, IIteratorContainer, IMethodData {
+               public MethodBuilder MethodBuilder;
+               public MethodData MethodData;
+               ReturnParameter return_attributes;
+               ListDictionary declarative_security;
+
+               /// <summary>
+               ///   Modifiers allowed in a class declaration
+               /// </summary>
+               const int AllowedModifiers =
+                       Modifiers.NEW |
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE |
+                       Modifiers.STATIC |
+                       Modifiers.VIRTUAL |
+                       Modifiers.SEALED |
+                       Modifiers.OVERRIDE |
+                       Modifiers.ABSTRACT |
+                       Modifiers.UNSAFE |
+                       Modifiers.METHOD_YIELDS | 
+                       Modifiers.EXTERN;
+
+               const int AllowedInterfaceModifiers =
+                       Modifiers.NEW | Modifiers.UNSAFE;
+
+               //
+               // return_type can be "null" for VOID values.
+               //
+               public Method (TypeContainer parent, GenericMethod generic,
+                              Expression return_type, int mod, bool is_iface,
+                              MemberName name, Parameters parameters, Attributes attrs,
+                              Location l)
+                       : base (parent, generic, return_type, mod,
+                               is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+                               is_iface, name, attrs, parameters, l)
+               {
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Method;
+                       }
+               }
+               
+               public override string GetSignatureForError()
+               {
+                       if (MethodBuilder == null) {
+                               return GetSignatureForError (Parent);
+                       }
+                       return TypeManager.CSharpSignature (MethodBuilder);
+               }
+
+               /// <summary>
+               /// Use this method when MethodBuilder is null
+               /// </summary>
+               public override string GetSignatureForError (TypeContainer tc)
+               {
+                       // TODO: get params from somewhere
+                       if (parameter_info == null)
+                               return base.GetSignatureForError (tc);
+
+                       // TODO: move to parameters
+                       System.Text.StringBuilder args = new System.Text.StringBuilder ();
+                       if (parameter_info.Parameters.FixedParameters != null) {
+                               for (int i = 0; i < parameter_info.Parameters.FixedParameters.Length; ++i) {
+                                       Parameter p = parameter_info.Parameters.FixedParameters [i];
+                                       args.Append (p.GetSignatureForError ());
+
+                                       if (i < parameter_info.Parameters.FixedParameters.Length - 1)
+                                               args.Append (',');
+                               }
+                       }
+
+                       return String.Concat (base.GetSignatureForError (tc), "(", args.ToString (), ")");
+               }
+
+                void DuplicateEntryPoint (MethodInfo b, Location location)
+                {
+                        Report.Error (
+                                17, location,
+                                "Program `" + CodeGen.FileName +
+                                "'  has more than one entry point defined: `" +
+                                TypeManager.CSharpSignature(b) + "'");
+                }
+
+                public bool IsEntryPoint (MethodBuilder b, InternalParameters pinfo)
+                {
+                        if (b.ReturnType != TypeManager.void_type &&
+                            b.ReturnType != TypeManager.int32_type)
+                                return false;
+
+                        if (pinfo.Count == 0)
+                                return true;
+
+                        if (pinfo.Count > 1)
+                                return false;
+
+                        Type t = pinfo.ParameterType(0);
+                        if (t.IsArray &&
+                            (t.GetArrayRank() == 1) &&
+                            (TypeManager.GetElementType(t) == TypeManager.string_type) &&
+                            (pinfo.ParameterModifier(0) == Parameter.Modifier.NONE))
+                                return true;
+                        else
+                                return false;
+                }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Target == AttributeTargets.ReturnValue) {
+                               if (return_attributes == null)
+                                       return_attributes = new ReturnParameter (MethodBuilder, Location);
+
+                               return_attributes.ApplyAttributeBuilder (a, cb);
+                               return;
+                       }
+
+                       if (a.Type == TypeManager.methodimpl_attr_type && a.IsInternalCall) {
+                               MethodBuilder.SetImplementationFlags (MethodImplAttributes.InternalCall | MethodImplAttributes.Runtime);
+                       }
+
+                       if (a.Type == TypeManager.dllimport_type) {
+                               const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
+                               if ((ModFlags & extern_static) != extern_static) {
+                                       Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
+                               }
+
+                               return;
+                       }
+
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
+                               if (declarative_security == null)
+                                       declarative_security = new ListDictionary ();
+                               a.ExtractSecurityPermissionSet (declarative_security);
+                               return;
+                       }
+
+                       if (a.Type == TypeManager.conditional_attribute_type) {
+                               if (IsOperator || IsExplicitImpl) {
+                                       Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
+                                       return;
+                               }
+
+                               if (ReturnType != TypeManager.void_type) {
+                                       Report.Error (578, Location, "Conditional not valid on '{0}' because its return new ErrorData ( type is not void", GetSignatureForError ());
+                                       return;
+                               }
+
+                               if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+                                       Report.Error (243, Location, "Conditional not valid on '{0}' because it is an override method", GetSignatureForError ());
+                                       return;
+                               }
+
+                               if (IsInterface) {
+                                       Report.Error (582, Location, "Conditional not valid on interface members");
+                                       return;
+                               }
+
+                               if (MethodData.IsImplementing) {
+                                       Report.Error (629, Location, "Conditional member '{0}' cannot implement interface member", GetSignatureForError ());
+                                       return;
+                               }
+
+                               for (int i = 0; i < parameter_info.Count; ++i) {
+                                       if ((parameter_info.ParameterModifier (i) & Parameter.Modifier.OUT) != 0) {
+                                               Report.Error (685, Location, "Conditional method '{0}' cannot have an out parameter", GetSignatureForError ());
+                                               return;
+                                       }
+                               }
+                       }
+
+                       MethodBuilder.SetCustomAttribute (cb);
+               }
+
+               protected override bool CheckForDuplications ()
+               {
+                       ArrayList ar = Parent.Methods;
+                       if (ar != null) {
+                               int arLen = ar.Count;
+                                       
+                               for (int i = 0; i < arLen; i++) {
+                                       Method m = (Method) ar [i];
+                                       if (IsDuplicateImplementation (m))
+                                               return false;
+                               }
+                       }
+
+                       ar = Parent.Properties;
+                       if (ar != null) {
+                               for (int i = 0; i < ar.Count; ++i) {
+                                       PropertyBase pb = (PropertyBase) ar [i];
+                                       if (pb.AreAccessorsDuplicateImplementation (this))
+                                               return false;
+                               }
+                       }
+
+                       ar = Parent.Indexers;
+                       if (ar != null) {
+                               for (int i = 0; i < ar.Count; ++i) {
+                                       PropertyBase pb = (PropertyBase) ar [i];
+                                       if (pb.AreAccessorsDuplicateImplementation (this))
+                                               return false;
+                               }
+                       }
+
+                       ar = Parent.Events;
+                       if (ar != null) {
+                               for (int i = 0; i < ar.Count; ++i) {
+                                       Event ev = (Event) ar [i];
+                                       if (ev.AreAccessorsDuplicateImplementation (this))
+                                               return false;
+                               }
+                       }
+
+                       return true;
+               }
+
+               //
+               // Creates the type
+               //
+               public override bool Define ()
+               {
+                       if (!DoDefineBase ())
+                               return false;
+
+                       MethodBuilder mb = null;
+                       if (GenericMethod != null) {
+                               string mname = MemberName.GetMethodName ();
+                               mb = Parent.TypeBuilder.DefineGenericMethod (mname, flags);
+                               if (!GenericMethod.Define (mb, ReturnType))
+                                       return false;
+                       }
+
+                       if (!DoDefine (ds))
+                               return false;
+
+                       if (!CheckBase ())
+                               return false;
+
+                       if (IsOperator)
+                               flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
+
+                       MethodData = new MethodData (this, ParameterInfo, ModFlags, flags,
+                                                    this, mb, GenericMethod, parent_method);
+
+                       if (!MethodData.Define (Parent))
+                               return false;
+
+                       //
+                       // Setup iterator if we are one
+                       //
+                       if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
+                               Iterator iterator = new Iterator (
+                                       Parent, Name, MemberType, ParameterTypes,
+                                       ParameterInfo, ModFlags, block, Location);
+
+                               if (!iterator.DefineIterator ())
+                                       return false;
+
+                               block = iterator.Block;
+                       }
+
+                       MethodBuilder = MethodData.MethodBuilder;
+
+                       //
+                       // This is used to track the Entry Point,
+                       //
+                       if (Name == "Main" &&
+                           ((ModFlags & Modifiers.STATIC) != 0) && RootContext.NeedsEntryPoint && 
+                           (RootContext.MainClass == null ||
+                            RootContext.MainClass == Parent.TypeBuilder.FullName)){
+                                if (IsEntryPoint (MethodBuilder, ParameterInfo)) {
+                                        if (RootContext.EntryPoint == null) {
+                                               if (Parent.IsGeneric){
+                                                       Report.Error (-201, Location,
+                                                                     "Entry point can not be defined in a generic class");
+                                               }
+                                               
+                                                RootContext.EntryPoint = MethodBuilder;
+                                                RootContext.EntryPointLocation = Location;
+                                        } else {
+                                                DuplicateEntryPoint (RootContext.EntryPoint, RootContext.EntryPointLocation);
+                                                DuplicateEntryPoint (MethodBuilder, Location);
+                                        }
+                                } else {
+                                       if (RootContext.WarningLevel >= 4)
+                                               Report.Warning (28, Location, "'{0}' has the wrong signature to be an entry point", TypeManager.CSharpSignature(MethodBuilder) );
+                               }
+                       }
+
+                       if (MemberType.IsAbstract && MemberType.IsSealed) {
+                               Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               //
+               // Emits the code
+               // 
+               public override void Emit ()
+               {
+                       MethodData.Emit (Parent, this);
+                       base.Emit ();
+
+                       if (declarative_security != null) {
+                               foreach (DictionaryEntry de in declarative_security) {
+                                       MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
+                               }
+                       }
+
+                       Block = null;
+                       MethodData = null;
+               }
+
+               protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
+               {
+                       MethodInfo mi = (MethodInfo) container.ParentCache.FindMemberToOverride (
+                               container.TypeBuilder, Name, ParameterTypes, false);
+
+                       if (mi == null)
+                               return null;
+
+                       parent_ret_type = mi.ReturnType;
+                       return mi;
+               }
+       
+               protected override bool VerifyClsCompliance(DeclSpace ds)
+               {
+                       if (!base.VerifyClsCompliance (ds))
+                               return false;
+
+                       if (parameter_types.Length > 0) {
+                               ArrayList al = (ArrayList)ds.MemberCache.Members [Name];
+                               if (al.Count > 1)
+                                       ds.MemberCache.VerifyClsParameterConflict (al, this, MethodBuilder);
+                       }
+
+                       return true;
+               }
+
+
+               void IIteratorContainer.SetYields ()
+               {
+                       ModFlags |= Modifiers.METHOD_YIELDS;
+               }
+
+               #region IMethodData Members
+
+               public CallingConventions CallingConventions {
+                       get {
+                               CallingConventions cc = Parameters.GetCallingConvention ();
+                               if (Parameters.HasArglist)
+                                       block.HasVarargs = true;
+
+                               if (!IsInterface)
+                                       if ((ModFlags & Modifiers.STATIC) == 0)
+                                               cc |= CallingConventions.HasThis;
+
+                               // FIXME: How is `ExplicitThis' used in C#?
+                       
+                               return cc;
+                       }
+               }
+
+               public Type ReturnType {
+                       get {
+                               return MemberType;
+                       }
+               }
+
+               public MemberName MethodName {
+                       get {
+                               return MemberName;
+                       }
+               }
+
+               public new Location Location {
+                       get {
+                               return base.Location;
+                       }
+               }
+
+               public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
+               {
+                       return new EmitContext (
+                               tc, ds, Location, ig, ReturnType, ModFlags, false);
+               }
+
+               public ObsoleteAttribute GetObsoleteAttribute ()
+               {
+                       return GetObsoleteAttribute (ds);
+               }
+
+               /// <summary>
+               /// Returns true if method has conditional attribute and the conditions is not defined (method is excluded).
+               /// </summary>
+               public bool IsExcluded (EmitContext ec)
+               {
+                       if ((caching_flags & Flags.Excluded_Undetected) == 0)
+                               return (caching_flags & Flags.Excluded) != 0;
+
+                       caching_flags &= ~Flags.Excluded_Undetected;
+
+                       if (parent_method == null) {
+                               if (OptAttributes == null)
+                                       return false;
+
+                               Attribute[] attrs = OptAttributes.SearchMulti (TypeManager.conditional_attribute_type, ec);
+
+                               if (attrs == null)
+                                       return false;
+
+                               foreach (Attribute a in attrs) {
+                                       string condition = a.GetConditionalAttributeValue (ds);
+                                       if (RootContext.AllDefines.Contains (condition))
+                                               return false;
+                               }
+
+                               caching_flags |= Flags.Excluded;
+                               return true;
+                       }
+
+                       IMethodData md = TypeManager.GetMethod (parent_method);
+                       if (md == null) {
+                               if (AttributeTester.IsConditionalMethodExcluded (parent_method)) {
+                                       caching_flags |= Flags.Excluded;
+                                       return true;
+                               }
+                               return false;
+                       }
+
+                       if (md.IsExcluded (ec)) {
+                               caching_flags |= Flags.Excluded;
+                               return true;
+                       }
+                       return false;
+               }
+
+               GenericMethod IMethodData.GenericMethod {
+                       get {
+                               return GenericMethod;
+                       }
+               }
+
+               #endregion
+       }
+
+       public abstract class ConstructorInitializer {
+               ArrayList argument_list;
+               protected ConstructorInfo parent_constructor;
+               Parameters parameters;
+               Location loc;
+               
+               public ConstructorInitializer (ArrayList argument_list, Parameters parameters,
+                                              Location loc)
+               {
+                       this.argument_list = argument_list;
+                       this.parameters = parameters;
+                       this.loc = loc;
+               }
+
+               public ArrayList Arguments {
+                       get {
+                               return argument_list;
+                       }
+               }
+
+               public bool Resolve (ConstructorBuilder caller_builder, EmitContext ec)
+               {
+                       Expression parent_constructor_group;
+                       Type t;
+
+                       ec.CurrentBlock = new ToplevelBlock (Block.Flags.Implicit, parameters, loc);
+
+                       if (argument_list != null){
+                               foreach (Argument a in argument_list){
+                                       if (!a.Resolve (ec, loc))
+                                               return false;
+                               }
+                       }
+                       ec.CurrentBlock = null;
+
+                       if (this is ConstructorBaseInitializer) {
+                               if (ec.ContainerType.BaseType == null)
+                                       return true;
+
+                               t = ec.ContainerType.BaseType;
+                               if (ec.ContainerType.IsValueType) {
+                                       Report.Error (522, loc,
+                                               "structs cannot call base class constructors");
+                                       return false;
+                               }
+                       } else
+                               t = ec.ContainerType;
+
+                       parent_constructor_group = Expression.MemberLookup (
+                               ec, t, ".ctor", MemberTypes.Constructor,
+                               BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                               loc);
+                       
+                       if (parent_constructor_group == null){
+                               parent_constructor_group = Expression.MemberLookup (
+                                       ec, t, ".ctor", MemberTypes.Constructor,
+                                       BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                                       loc);
+
+                               if (parent_constructor_group != null)
+                                       Report.Error (
+                                               112, loc, "`{0}.{1}' is inaccessible due to " +
+                                               "its protection level", t.FullName, t.Name);
+                               else
+                                       Report.Error (
+                                               1501, loc, "Can not find a constructor for " +
+                                               "this argument list");
+                               return false;
+                       }
+                       
+                       parent_constructor = (ConstructorInfo) Invocation.OverloadResolve (
+                               ec, (MethodGroupExpr) parent_constructor_group, argument_list,
+                               false, loc);
+                       
+                       if (parent_constructor == null){
+                               Report.Error (1501, loc,
+                                      "Can not find a constructor for this argument list");
+                               return false;
+                       }
+                       
+                       if (parent_constructor == caller_builder){
+                               Report.Error (516, String.Format ("Constructor `{0}' can not call itself", TypeManager.CSharpSignature (caller_builder)));
+                               return false;
+                       }
+                       
+                       return true;
+               }
+
+               public void Emit (EmitContext ec)
+               {
+                       if (parent_constructor != null){
+                               ec.Mark (loc, false);
+                               if (ec.IsStatic)
+                                       Invocation.EmitCall (ec, true, true, null, parent_constructor, argument_list, loc);
+                               else
+                                       Invocation.EmitCall (ec, true, false, ec.GetThis (loc), parent_constructor, argument_list, loc);
+                       }
+               }
+
+               /// <summary>
+               /// Method search for base ctor. (We do not cache it).
+               /// </summary>
+               Constructor GetOverloadedConstructor (TypeContainer tc)
+               {
+                       if (tc.InstanceConstructors == null)
+                               return null;
+
+                       foreach (Constructor c in tc.InstanceConstructors) {
+                               if (Arguments == null) {
+                                       if (c.ParameterTypes.Length == 0)
+                                               return c;
+
+                                       continue;
+                               }
+
+                               bool ok = true;
+
+                               int count = c.ParameterInfo.Count;
+                               if ((count > 0) &&
+                                   c.ParameterInfo.ParameterModifier (count - 1) == Parameter.Modifier.PARAMS) {
+                                       for (int i = 0; i < count-1; i++)
+                                               if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
+                                                       ok = false;
+                                                       break;
+                                               }
+                               } else {
+                                       if (c.ParameterTypes.Length != Arguments.Count)
+                                               continue;
+
+                                       for (int i = 0; i < Arguments.Count; ++i)
+                                               if (c.ParameterTypes [i] != ((Argument)Arguments [i]).Type) {
+                                                       ok = false;
+                                                       break;
+                                               }
+                               }
+
+                               if (!ok)
+                                       continue;
+
+                               return c;
+                       }
+
+                       return null;
+               }
+
+               //TODO: implement caching when it will be necessary
+               public virtual void CheckObsoleteAttribute (TypeContainer tc, Location loc)
+               {
+                       Constructor ctor = GetOverloadedConstructor (tc);
+                       if (ctor == null)
+                               return;
+
+                       ObsoleteAttribute oa = ctor.GetObsoleteAttribute (tc);
+                       if (oa == null)
+                               return;
+
+                       AttributeTester.Report_ObsoleteMessage (oa, ctor.GetSignatureForError (), loc);
+               }
+       }
+
+       public class ConstructorBaseInitializer : ConstructorInitializer {
+               public ConstructorBaseInitializer (ArrayList argument_list, Parameters pars, Location l) :
+                       base (argument_list, pars, l)
+               {
+               }
+
+               public override void CheckObsoleteAttribute(TypeContainer tc, Location loc) {
+                       if (parent_constructor == null)
+                               return;
+
+                       TypeContainer type_ds = TypeManager.LookupTypeContainer (tc.TypeBuilder.BaseType);
+                       if (type_ds == null) {
+                               ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (parent_constructor);
+
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (parent_constructor), loc);
+
+                               return;
+                       }
+
+                       base.CheckObsoleteAttribute (type_ds, loc);
+               }
+
+       }
+
+       public class ConstructorThisInitializer : ConstructorInitializer {
+               public ConstructorThisInitializer (ArrayList argument_list, Parameters pars, Location l) :
+                       base (argument_list, pars, l)
+               {
+               }
+       }
+       
+       public class Constructor : MethodCore, IMethodData {
+               public ConstructorBuilder ConstructorBuilder;
+               public ConstructorInitializer Initializer;
+               ListDictionary declarative_security;
+
+               // <summary>
+               //   Modifiers allowed for a constructor.
+               // </summary>
+               public const int AllowedModifiers =
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.STATIC |
+                       Modifiers.UNSAFE |
+                       Modifiers.EXTERN |              
+                       Modifiers.PRIVATE;
+
+               bool has_compliant_args = false;
+               //
+               // The spec claims that static is not permitted, but
+               // my very own code has static constructors.
+               //
+               public Constructor (TypeContainer ds, string name, int mod, Parameters args,
+                                   ConstructorInitializer init, Location l)
+                       : base (ds, null, null, mod, AllowedModifiers, false,
+                               new MemberName (name), null, args, l)
+               {
+                       Initializer = init;
+               }
+
+               public override string GetSignatureForError()
+               {
+                       if (ConstructorBuilder == null)
+                               return GetSignatureForError (Parent);
+
+                       return TypeManager.CSharpSignature (ConstructorBuilder);
+               }
+
+               public bool HasCompliantArgs {
+                       get {
+                               return has_compliant_args;
+                       }
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Constructor;
+                       }
+               }
+
+
+               //
+               // Returns true if this is a default constructor
+               //
+               public bool IsDefault ()
+               {
+                       if ((ModFlags & Modifiers.STATIC) != 0)
+                               return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
+                                       (Parameters.ArrayParameter == null ? true : Parameters.Empty);
+                       
+                       else
+                               return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
+                                       (Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
+                                       (Initializer is ConstructorBaseInitializer) &&
+                                       (Initializer.Arguments == null);
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
+                               if (declarative_security == null) {
+                                       declarative_security = new ListDictionary ();
+                               }
+                               a.ExtractSecurityPermissionSet (declarative_security);
+                               return;
+                       }
+
+                       ConstructorBuilder.SetCustomAttribute (cb);
+               }
+
+               protected override bool CheckForDuplications ()
+               {
+                       ArrayList ar = Parent.InstanceConstructors;
+                       if (ar != null) {
+                               int arLen = ar.Count;
+                                       
+                               for (int i = 0; i < arLen; i++) {
+                                       Constructor m = (Constructor) ar [i];
+                                       if (IsDuplicateImplementation (m))
+                                               return false;
+                               }
+                       }
+                       return true;
+               }
+                       
+               protected override bool CheckBase ()
+               {
+                       // Check whether arguments were correct.
+                       if (!DoDefineParameters ())
+                               return false;
+                       
+                       // TODO: skip the rest for generated ctor
+                       if ((ModFlags & Modifiers.STATIC) != 0)
+                               return true;
+                       
+                       if (!CheckForDuplications ())
+                               return false;
+
+                       if (Parent.Kind == Kind.Struct) {
+                               if (ParameterTypes.Length == 0) {
+                               Report.Error (568, Location, 
+                                       "Structs can not contain explicit parameterless " +
+                                       "constructors");
+                               return false;
+                       }
+                               
+                               if ((ModFlags & Modifiers.PROTECTED) != 0) {
+                                       Report.Error (666, Location, "Protected member in struct declaration");
+                                               return false;
+                               }
+                       }
+                       
+                       if ((RootContext.WarningLevel >= 4) && ((Parent.ModFlags & Modifiers.SEALED) != 0 && (ModFlags & Modifiers.PROTECTED) != 0)) {
+                               Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
+                       }
+                       
+                       return true;
+               }
+               
+               //
+               // Creates the ConstructorBuilder
+               //
+               public override bool Define ()
+               {
+                       MethodAttributes ca = (MethodAttributes.RTSpecialName |
+                                              MethodAttributes.SpecialName);
+
+                       if ((ModFlags & Modifiers.STATIC) != 0){
+                               ca |= MethodAttributes.Static | MethodAttributes.Private;
+                       } else {
+                               ca |= MethodAttributes.HideBySig;
+
+                               if ((ModFlags & Modifiers.PUBLIC) != 0)
+                                       ca |= MethodAttributes.Public;
+                               else if ((ModFlags & Modifiers.PROTECTED) != 0){
+                                       if ((ModFlags & Modifiers.INTERNAL) != 0)
+                                               ca |= MethodAttributes.FamORAssem;
+                                       else 
+                                               ca |= MethodAttributes.Family;
+                               } else if ((ModFlags & Modifiers.INTERNAL) != 0)
+                                       ca |= MethodAttributes.Assembly;
+                               else if (IsDefault ())
+                                       ca |= MethodAttributes.Public;
+                               else
+                                       ca |= MethodAttributes.Private;
+                       }
+
+                       // Check if arguments were correct.
+                       if (!CheckBase ())
+                               return false;
+
+                       ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
+                               ca, CallingConventions,
+                               ParameterTypes);
+
+                       if ((ModFlags & Modifiers.UNSAFE) != 0)
+                               ConstructorBuilder.InitLocals = false;
+                       
+                       TypeManager.AddMethod (ConstructorBuilder, this);
+
+                       //
+                       // HACK because System.Reflection.Emit is lame
+                       //
+                       TypeManager.RegisterMethod (ConstructorBuilder, ParameterInfo, ParameterTypes);
+
+                       return true;
+               }
+
+               //
+               // Emits the code
+               //
+               public override void Emit ()
+               {
+                       EmitContext ec = CreateEmitContext (null, null);
+
+                       //
+                       // extern methods have no bodies
+                       //
+                       if ((ModFlags & Modifiers.EXTERN) != 0) {
+                               if ((block != null) && ((ModFlags & Modifiers.EXTERN) != 0)) {
+                                       Report.Error (
+                                               179, Location, "External constructor `" +
+                                               TypeManager.CSharpSignature (ConstructorBuilder) +
+                                               "' can not have a body");
+                                       return;
+                               }
+                       } else if (block == null) {
+                               Report.Error (
+                                       501, Location, "Constructor `" +
+                                       TypeManager.CSharpSignature (ConstructorBuilder) +
+                                       "' must declare a body since it is not marked extern");
+                               return;
+                       }
+
+                       if ((ModFlags & Modifiers.STATIC) == 0){
+                               if (Parent.Kind == Kind.Class && Initializer == null)
+                                       Initializer = new ConstructorBaseInitializer (
+                                               null, Parameters.EmptyReadOnlyParameters, Location);
+
+
+                               //
+                               // Spec mandates that Initializers will not have
+                               // `this' access
+                               //
+                               ec.IsStatic = true;
+                               if (Initializer != null && !Initializer.Resolve (ConstructorBuilder, ec))
+                                       return;
+                               ec.IsStatic = false;
+                       }
+
+                       Parameters.LabelParameters (ec, ConstructorBuilder, Location);
+                       
+                       SourceMethod source = SourceMethod.Create (
+                               Parent, ConstructorBuilder, block);
+
+                       //
+                       // Classes can have base initializers and instance field initializers.
+                       //
+                       if (Parent.Kind == Kind.Class){
+                               if ((ModFlags & Modifiers.STATIC) == 0){
+
+                                       //
+                                       // If we use a "this (...)" constructor initializer, then
+                                       // do not emit field initializers, they are initialized in the other constructor
+                                       //
+                                       if (!(Initializer != null && Initializer is ConstructorThisInitializer))
+                                               Parent.EmitFieldInitializers (ec);
+                               }
+                       }
+                       if (Initializer != null) {
+                               if (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent.Parent) == null)
+                                       Initializer.CheckObsoleteAttribute (Parent, Location);
+                               else
+                                       ec.TestObsoleteMethodUsage = false;
+                               Initializer.Emit (ec);
+                       }
+                       
+                       if ((ModFlags & Modifiers.STATIC) != 0)
+                               Parent.EmitFieldInitializers (ec);
+
+                       if (OptAttributes != null) 
+                               OptAttributes.Emit (ec, this);
+
+                       // If this is a non-static `struct' constructor and doesn't have any
+                       // initializer, it must initialize all of the struct's fields.
+                       if ((Parent.Kind == Kind.Struct) &&
+                           ((ModFlags & Modifiers.STATIC) == 0) && (Initializer == null))
+                               Block.AddThisVariable (Parent, Location);
+
+                       ec.EmitTopBlock (block, ParameterInfo, Location);
+
+                       if (source != null)
+                               source.CloseMethod ();
+
+                       base.Emit ();
+
+                       if (declarative_security != null) {
+                               foreach (DictionaryEntry de in declarative_security) {
+                                       ConstructorBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
+                               }
+                       }
+
+                       block = null;
+               }
+
+               // Is never override
+               protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
+               {
+                       return null;
+               }
+                                               
+               protected override bool VerifyClsCompliance (DeclSpace ds)
+               {
+                       if (!base.VerifyClsCompliance (ds) || !IsExposedFromAssembly (ds)) {
+                               return false;
+                       }
+
+                       if (parameter_types.Length > 0) {
+                               ArrayList al = (ArrayList)ds.MemberCache.Members [".ctor"];
+                               if (al.Count > 3)
+                                       ds.MemberCache.VerifyClsParameterConflict (al, this, ConstructorBuilder);
+                               
+                               if (ds.TypeBuilder.IsSubclassOf (TypeManager.attribute_type)) {
+                                       foreach (Type param in parameter_types) {
+                                               if (param.IsArray) {
+                                                       return true;
+                               }
+                       }
+                               }
+                       }
+                       has_compliant_args = true;
+                               return true;
+               }
+
+               #region IMethodData Members
+
+               public System.Reflection.CallingConventions CallingConventions {
+                       get {
+                               CallingConventions cc = Parameters.GetCallingConvention ();
+
+                               if (Parent.Kind == Kind.Class)
+                                       if ((ModFlags & Modifiers.STATIC) == 0)
+                                               cc |= CallingConventions.HasThis;
+
+                               // FIXME: How is `ExplicitThis' used in C#?
+                       
+                               return cc;
+                               }
+                       }
+                       
+               public new Location Location {
+                       get {
+                               return base.Location;
+                       }
+               }
+
+               public MemberName MethodName {
+                       get {
+                               return MemberName;
+                       }
+               }
+                       
+               public Type ReturnType {
+                       get {
+                               return MemberType;
+                       }
+               }
+
+               public EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig)
+               {
+                       ILGenerator ig_ = ConstructorBuilder.GetILGenerator ();
+                       return new EmitContext (Parent, Location, ig_, null, ModFlags, true);
+                       }
+
+               public ObsoleteAttribute GetObsoleteAttribute ()
+               {
+                       return null;
+               }
+
+               public bool IsExcluded(EmitContext ec)
+               {
+                       return false;
+               }
+
+               GenericMethod IMethodData.GenericMethod {
+                       get {
+                               return null;
+                       }
+               }
+
+               #endregion
+       }
+
+       /// <summary>
+       /// Interface for MethodData class. Holds links to parent members to avoid member duplication.
+       /// </summary>
+       public interface IMethodData
+       {
+               CallingConventions CallingConventions { get; }
+               Location Location { get; }
+               MemberName MethodName { get; }
+               Type[] ParameterTypes { get; }
+               Type ReturnType { get; }
+               GenericMethod GenericMethod { get; }
+
+               Attributes OptAttributes { get; }
+               ToplevelBlock Block { get; }
+
+               EmitContext CreateEmitContext (TypeContainer tc, ILGenerator ig);
+               ObsoleteAttribute GetObsoleteAttribute ();
+               string GetSignatureForError (TypeContainer tc);
+               bool IsExcluded (EmitContext ec);
+               bool IsClsCompliaceRequired (DeclSpace ds);
+       }
+
+       //
+       // Encapsulates most of the Method's state
+       //
+       public class MethodData {
+
+               readonly IMethodData method;
+
+               //
+               // The return type of this method
+               //
+               public readonly GenericMethod GenericMethod;
+               public readonly InternalParameters ParameterInfo;
+
+               //
+               // Are we implementing an interface ?
+               //
+               public bool IsImplementing = false;
+
+               //
+               // Protected data.
+               //
+               protected MemberBase member;
+               protected int modifiers;
+               protected MethodAttributes flags;
+               protected Type declaring_type;
+               protected MethodInfo parent_method;
+
+               EmitContext ec;
+
+               MethodBuilder builder = null;
+               public MethodBuilder MethodBuilder {
+                       get {
+                               return builder;
+                       }
+               }
+
+               public Type DeclaringType {
+                       get {
+                               return declaring_type;
+                       }
+               }
+
+               public MethodData (MemberBase member, InternalParameters parameters,
+                                  int modifiers, MethodAttributes flags, IMethodData method)
+               {
+                       this.member = member;
+                       this.ParameterInfo = parameters;
+                       this.modifiers = modifiers;
+                       this.flags = flags;
+
+                       this.method = method;
+               }
+
+               public MethodData (MemberBase member, InternalParameters parameters,
+                                  int modifiers, MethodAttributes flags, 
+                                  IMethodData method, MethodBuilder builder,
+                                  GenericMethod generic, MethodInfo parent_method)
+                       : this (member, parameters, modifiers, flags, method)
+               {
+                       this.builder = builder;
+                       this.GenericMethod = generic;
+                       this.parent_method = parent_method;
+               }
+
+               static string RemoveArity (string name)
+               {
+                       int start = 0;
+                       StringBuilder sb = new StringBuilder ();
+                       while (start < name.Length) {
+                               int pos = name.IndexOf ('`', start);
+                               if (pos < 0) {
+                                       sb.Append (name.Substring (start));
+                                       break;
+                               }
+
+                               sb.Append (name.Substring (start, pos-start));
+
+                               pos++;
+                               while ((pos < name.Length) && Char.IsNumber (name [pos]))
+                                       pos++;
+
+                               start = pos;
+                       }
+
+                       return sb.ToString ();
+               }
+
+               public bool Define (TypeContainer container)
+               {
+                       MethodInfo implementing = null;
+
+                       string prefix;
+                       if (member.IsExplicitImpl)
+                               prefix = member.InterfaceType.FullName + ".";
+                       else
+                               prefix = "";
+
+                       string name = method.MethodName.Basename;
+                       string method_name = prefix + name;
+
+                       Type[] ParameterTypes = method.ParameterTypes;
+
+                       if (container.Pending != null){
+                               if (member is Indexer)
+                                       implementing = container.Pending.IsInterfaceIndexer (
+                                               member.InterfaceType, method.ReturnType, ParameterTypes);
+                               else
+                                       implementing = container.Pending.IsInterfaceMethod (
+                                               member.InterfaceType, name, method.ReturnType, ParameterTypes);
+
+                               if (member.InterfaceType != null){
+                                       if (implementing == null){
+                                               Report.Error (539, method.Location,
+                                                             "'{0}' in explicit interface declaration is not an interface", method_name);
+                                               return false;
+                                       }
+                               }
+                       }
+
+                       //
+                       // For implicit implementations, make sure we are public, for
+                       // explicit implementations, make sure we are private.
+                       //
+                       if (implementing != null){
+                               //
+                               // Setting null inside this block will trigger a more
+                               // verbose error reporting for missing interface implementations
+                               //
+                               // The "candidate" function has been flagged already
+                               // but it wont get cleared
+                               //
+                               if (member.IsExplicitImpl){
+                                       if ((modifiers & (Modifiers.PUBLIC | Modifiers.ABSTRACT | Modifiers.VIRTUAL)) != 0){
+                                               Modifiers.Error_InvalidModifier (method.Location, "public, virtual or abstract");
+                                               implementing = null;
+                                       }
+                               } else if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public){
+                                       if (TypeManager.IsInterfaceType (implementing.DeclaringType)){
+                                               //
+                                               // If this is an interface method implementation,
+                                               // check for public accessibility
+                                               //
+                                               implementing = null;
+                                       } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){
+                                               // We may never be private.
+                                               implementing = null;
+                                       } else if ((modifiers & Modifiers.OVERRIDE) == 0){
+                                               //
+                                               // We may be protected if we're overriding something.
+                                               //
+                                               implementing = null;
+                                       }
+                               } 
+                                       
+                               //
+                               // Static is not allowed
+                               //
+                               if ((modifiers & Modifiers.STATIC) != 0){
+                                       implementing = null;
+                                       Modifiers.Error_InvalidModifier (method.Location, "static");
+                               }
+                       }
+                       
+                       //
+                       // If implementing is still valid, set flags
+                       //
+                       if (implementing != null){
+                               //
+                               // When implementing interface methods, set NewSlot
+                               // unless, we are overwriting a method.
+                               //
+                               if (implementing.DeclaringType.IsInterface){
+                                       if ((modifiers & Modifiers.OVERRIDE) == 0)
+                                               flags |= MethodAttributes.NewSlot;
+                               }
+                               flags |=
+                                       MethodAttributes.Virtual |
+                                       MethodAttributes.HideBySig;
+
+                               // Set Final unless we're virtual, abstract or already overriding a method.
+                               if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
+                                       flags |= MethodAttributes.Final;
+
+                               IsImplementing = true;
+                       }
+
+                       EmitContext ec = method.CreateEmitContext (container, null);
+
+                       DefineMethodBuilder (ec, container, method_name, ParameterTypes);
+
+                       if (builder == null)
+                               return false;
+
+                       if (container.CurrentType != null)
+                               declaring_type = container.CurrentType;
+                       else
+                               declaring_type = container.TypeBuilder;
+
+                       if ((modifiers & Modifiers.UNSAFE) != 0)
+                               builder.InitLocals = false;
+
+                       if (IsImplementing){
+                               //
+                               // clear the pending implemntation flag
+                               //
+                               if (member is Indexer) {
+                                       container.Pending.ImplementIndexer (
+                                               member.InterfaceType, builder, method.ReturnType,
+                                               ParameterTypes, member.IsExplicitImpl);
+                               } else
+                                       container.Pending.ImplementMethod (
+                                               member.InterfaceType, name, method.ReturnType,
+                                               ParameterTypes, member.IsExplicitImpl);
+
+                               if (member.IsExplicitImpl)
+                                       container.TypeBuilder.DefineMethodOverride (
+                                               builder, implementing);
+
+                       }
+
+                       TypeManager.RegisterMethod (builder, ParameterInfo, ParameterTypes);
+                       TypeManager.AddMethod (builder, method);
+
+                       if (GenericMethod != null) {
+                               bool is_override = member.IsExplicitImpl |
+                                       ((modifiers & Modifiers.OVERRIDE) != 0);
+
+                               if (implementing != null)
+                                       parent_method = implementing;
+
+                               if (!GenericMethod.DefineType (ec, builder, parent_method, is_override))
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               /// <summary>
+               /// Create the MethodBuilder for the method 
+               /// </summary>
+               void DefineMethodBuilder (EmitContext ec, TypeContainer container, string method_name, Type[] ParameterTypes)
+               {
+                       const int extern_static = Modifiers.EXTERN | Modifiers.STATIC;
+
+                       if ((modifiers & extern_static) == extern_static) {
+
+                               if (method.OptAttributes != null) {
+                                       Attribute dllimport_attribute = method.OptAttributes.Search (TypeManager.dllimport_type, ec);
+                                       if (dllimport_attribute != null) {
+                                               flags |= MethodAttributes.PinvokeImpl;
+                                               builder = dllimport_attribute.DefinePInvokeMethod (
+                                                       ec, container.TypeBuilder, method_name, flags,
+                                                       method.ReturnType, ParameterTypes);
+
+                                               return;
+                                       }
+                               }
+
+                               // for extern static method must be specified either DllImport attribute or MethodImplAttribute.
+                               // We are more strict than Microsoft and report CS0626 like error
+                               if (method.OptAttributes == null ||
+                                       !method.OptAttributes.Contains (TypeManager.methodimpl_attr_type, ec)) {
+                                       Report.Error (626, method.Location, "Method, operator, or accessor '{0}' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation", method.GetSignatureForError (container));
+                                       return;
+                               }
+                       }
+
+                       if (builder == null)
+                               builder = container.TypeBuilder.DefineMethod (
+                                       method_name, flags, method.CallingConventions,
+                                       method.ReturnType, ParameterTypes);
+                       else
+                               builder.SetGenericMethodSignature (
+                                       flags, method.CallingConventions,
+                                       method.ReturnType, ParameterTypes);
+               }
+
+               //
+               // Emits the code
+               // 
+               public void Emit (TypeContainer container, Attributable kind)
+               {
+                       EmitContext ec;
+                       if ((flags & MethodAttributes.PinvokeImpl) == 0)
+                               ec = method.CreateEmitContext (container, builder.GetILGenerator ());
+                       else
+                               ec = method.CreateEmitContext (container, null);
+
+                       if (method.GetObsoleteAttribute () != null || container.GetObsoleteAttribute (container.Parent) != null)
+                               ec.TestObsoleteMethodUsage = false;
+
+                       Location loc = method.Location;
+                       Attributes OptAttributes = method.OptAttributes;
+
+                       if (OptAttributes != null)
+                               OptAttributes.Emit (ec, kind);
+
+                       if (member is MethodCore)
+                               ((MethodCore) member).Parameters.LabelParameters (ec, MethodBuilder, loc);
+                        
+                       SymbolWriter sw = CodeGen.SymbolWriter;
+                       ToplevelBlock block = method.Block;
+                       
+                       //
+                       // abstract or extern methods have no bodies
+                       //
+                       if ((modifiers & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0){
+                               if (block == null)
+                                       return;
+
+                               //
+                               // abstract or extern methods have no bodies.
+                               //
+                               if ((modifiers & Modifiers.ABSTRACT) != 0)
+                                       Report.Error (
+                                               500, method.Location, "Abstract method `" +
+                                               TypeManager.CSharpSignature (builder) +
+                                               "' can not have a body");
+
+                               if ((modifiers & Modifiers.EXTERN) != 0)
+                                       Report.Error (
+                                               179, method.Location, "External method `" +
+                                               TypeManager.CSharpSignature (builder) +
+                                               "' can not have a body");
+
+                               return;
+                       }
+
+                       //
+                       // Methods must have a body unless they're extern or abstract
+                       //
+                       if (block == null) {
+                               Report.Error (
+                                       501, method.Location, "Method `" +
+                                       TypeManager.CSharpSignature (builder) +
+                                       "' must declare a body since it is not marked " +
+                                       "abstract or extern");
+                               return;
+                       }
+
+                       SourceMethod source = SourceMethod.Create (
+                               container, MethodBuilder, method.Block);
+
+                       //
+                       // Handle destructors specially
+                       //
+                       // FIXME: This code generates buggy code
+                       //
+                       if (member is Destructor)
+                               EmitDestructor (ec, block);
+                       else
+                               ec.EmitTopBlock (block, ParameterInfo, loc);
+
+                       if (source != null)
+                               source.CloseMethod ();
+               }
+
+               void EmitDestructor (EmitContext ec, ToplevelBlock block)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       Label finish = ig.DefineLabel ();
+
+                       block.SetDestructor ();
+                       
+                       ig.BeginExceptionBlock ();
+                       ec.ReturnLabel = finish;
+                       ec.HasReturnLabel = true;
+                       ec.EmitTopBlock (block, null, method.Location);
+                       
+                       // ig.MarkLabel (finish);
+                       ig.BeginFinallyBlock ();
+                       
+                       if (ec.ContainerType.BaseType != null) {
+                               Expression member_lookup = Expression.MemberLookup (
+                                       ec, ec.ContainerType.BaseType, null, ec.ContainerType.BaseType,
+                                       "Finalize", MemberTypes.Method, Expression.AllBindingFlags, method.Location);
+
+                               if (member_lookup != null){
+                                       MethodGroupExpr parent_destructor = ((MethodGroupExpr) member_lookup);
+                               
+                                       ig.Emit (OpCodes.Ldarg_0);
+                                       ig.Emit (OpCodes.Call, (MethodInfo) parent_destructor.Methods [0]);
+                               }
+                       }
+                       
+                       ig.EndExceptionBlock ();
+                       //ig.MarkLabel (ec.ReturnLabel);
+                       ig.Emit (OpCodes.Ret);
+               }
+       }
+
+       public class Destructor : Method {
+
+               public Destructor (TypeContainer ds, Expression return_type, int mod, string name,
+                                  Parameters parameters, Attributes attrs, Location l)
+                       : base (ds, null, return_type, mod, false, new MemberName (name),
+                               parameters, attrs, l)
+               { }
+
+               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type == TypeManager.conditional_attribute_type) {
+                               Report.Error (577, Location, "Conditional not valid on '{0}' because it is a destructor, operator, or explicit interface implementation", GetSignatureForError ());
+                               return;
+                       }
+
+                       base.ApplyAttributeBuilder (a, cb);
+               }
+       }
+       
+       abstract public class MemberBase : MemberCore {
+               public Expression Type;
+
+               public MethodAttributes flags;
+
+               protected readonly int explicit_mod_flags;
+
+               //
+               // The "short" name of this property / indexer / event.  This is the
+               // name without the explicit interface.
+               //
+               public string ShortName;
+
+               //
+               // The type of this property / indexer / event
+               //
+               public Type MemberType;
+
+               //
+               // If true, this is an explicit interface implementation
+               //
+               public bool IsExplicitImpl = false;
+
+               //
+               // The name of the interface we are explicitly implementing
+               //
+               public MemberName ExplicitInterfaceName = null;
+
+               //
+               // Whether this is an interface member.
+               //
+               public bool IsInterface;
+
+               //
+               // If true, the interface type we are explicitly implementing
+               //
+               public Type InterfaceType = null;
+
+               //
+               // The constructor is only exposed to our children
+               //
+               protected MemberBase (TypeContainer parent, Expression type, int mod,
+                                     int allowed_mod, int def_mod, MemberName name,
+                                     Attributes attrs, Location loc)
+                       : base (parent, name, attrs, loc)
+               {
+                       explicit_mod_flags = mod;
+                       Type = type;
+                       ModFlags = Modifiers.Check (allowed_mod, mod, def_mod, loc);
+
+                       // Check for explicit interface implementation
+                       if (MemberName.Left != null) {
+                               ExplicitInterfaceName = MemberName.Left;
+                               ShortName = MemberName.Name;
+                               IsExplicitImpl = true;
+                       } else
+                               ShortName = Name;
+               }
+
+               protected virtual bool CheckBase ()
+               {
+                       if ((ModFlags & Modifiers.PROTECTED) != 0 && Parent.Kind == Kind.Struct) {
+                               Report.Error (666, Location, "Protected member in struct declaration");
+                               return false;
+                       }
+
+                       if ((RootContext.WarningLevel >= 4) &&
+                           ((Parent.ModFlags & Modifiers.SEALED) != 0) &&
+                           ((ModFlags & Modifiers.PROTECTED) != 0) &&
+                           ((ModFlags & Modifiers.OVERRIDE) == 0) && (Name != "Finalize")) {
+                               Report.Warning (628, Location, "'{0}': new protected member declared in sealed class", GetSignatureForError (Parent));
+                       }
+
+                       return true;
+               }
+
+               protected abstract bool CheckGenericOverride (MethodInfo method, string name);
+
+               protected virtual bool CheckParameters (DeclSpace ds, Type [] parameters)
+               {
+                       bool error = false;
+
+                       foreach (Type partype in parameters){
+                               if (partype == TypeManager.void_type) {
+                                       Report.Error (
+                                               1547, Location, "Keyword 'void' cannot " +
+                                               "be used in this context");
+                                       return false;
+                               }
+
+                               if (partype.IsPointer){
+                                       if (!UnsafeOK (ds))
+                                               error = true;
+                                       if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (partype), Location))
+                                               error = true;
+                               }
+
+                               if (ds.AsAccessible (partype, ModFlags))
+                                       continue;
+
+                               if (this is Indexer)
+                                       Report.Error (55, Location,
+                                                     "Inconsistent accessibility: parameter type `" +
+                                                     TypeManager.CSharpName (partype) + "' is less " +
+                                                     "accessible than indexer `" + Name + "'");
+                               else if ((this is Method) && ((Method) this).IsOperator)
+                                       Report.Error (57, Location,
+                                                     "Inconsistent accessibility: parameter type `" +
+                                                     TypeManager.CSharpName (partype) + "' is less " +
+                                                     "accessible than operator `" + Name + "'");
+                               else
+                                       Report.Error (51, Location,
+                                                     "Inconsistent accessibility: parameter type `" +
+                                                     TypeManager.CSharpName (partype) + "' is less " +
+                                                     "accessible than method `" + Name + "'");
+                               error = true;
+                       }
+
+                       return !error;
+               }
+
+               protected virtual bool DoDefineBase ()
+               {
+                       EmitContext ec = Parent.EmitContext;
+                       if (ec == null)
+                               throw new InternalErrorException ("MemberBase.DoDefine called too early");
+
+                       if (Name == null)
+                               throw new InternalErrorException ();
+
+                       if (IsInterface) {
+                               ModFlags = Modifiers.PUBLIC |
+                                       Modifiers.ABSTRACT |
+                                       Modifiers.VIRTUAL | (ModFlags & Modifiers.UNSAFE) | (ModFlags & Modifiers.NEW);
+
+                               flags = MethodAttributes.Public |
+                                       MethodAttributes.Abstract |
+                                       MethodAttributes.HideBySig |
+                                       MethodAttributes.NewSlot |
+                                       MethodAttributes.Virtual;
+                       } else {
+                               if (!Parent.MethodModifiersValid (ModFlags, Name, Location))
+                                       return false;
+
+                               flags = Modifiers.MethodAttr (ModFlags);
+                       }
+
+                       return true;
+               }
+
+               protected virtual bool DoDefine (DeclSpace decl)
+               {
+                       EmitContext ec = decl.EmitContext;
+                       if (ec == null)
+                               throw new InternalErrorException ("MemberBase.DoDefine called too early");
+
+                       ec.InUnsafe = InUnsafe;
+
+                       // Lookup Type, verify validity
+                       bool old_unsafe = ec.InUnsafe;
+                       ec.InUnsafe = InUnsafe;
+                       TypeExpr texpr = Type.ResolveAsTypeTerminal (ec);
+                       ec.InUnsafe = old_unsafe;
+
+                       if (texpr == null)
+                               return false;
+
+                       MemberType = texpr.Type;
+
+                       if ((Parent.ModFlags & Modifiers.SEALED) != 0){
+                               if ((ModFlags & (Modifiers.VIRTUAL|Modifiers.ABSTRACT)) != 0){
+                                       Report.Error (549, Location, "Virtual method can not be contained in sealed class");
+                                       return false;
+                               }
+                       }
+                       
+                       // verify accessibility
+                       if (!Parent.AsAccessible (MemberType, ModFlags)) {
+                               if (this is Property)
+                                       Report.Error (53, Location,
+                                                     "Inconsistent accessibility: property type `" +
+                                                     TypeManager.CSharpName (MemberType) + "' is less " +
+                                                     "accessible than property `" + Name + "'");
+                               else if (this is Indexer)
+                                       Report.Error (54, Location,
+                                                     "Inconsistent accessibility: indexer return type `" +
+                                                     TypeManager.CSharpName (MemberType) + "' is less " +
+                                                     "accessible than indexer `" + Name + "'");
+                               else if (this is MethodCore) {
+                                       if (this is Operator)
+                                               Report.Error (56, Location,
+                                                             "Inconsistent accessibility: return type `" +
+                                                             TypeManager.CSharpName (MemberType) + "' is less " +
+                                                             "accessible than operator `" + Name + "'");
+                                       else
+                                               Report.Error (50, Location,
+                                                             "Inconsistent accessibility: return type `" +
+                                                             TypeManager.CSharpName (MemberType) + "' is less " +
+                                                             "accessible than method `" + Name + "'");
+                               } else {
+                                       Report.Error (52, Location,
+                                                     "Inconsistent accessibility: field type `" +
+                                                     TypeManager.CSharpName (MemberType) + "' is less " +
+                                                     "accessible than field `" + Name + "'");
+                               }
+                               return false;
+                       }
+
+                       if (MemberType.IsPointer && !UnsafeOK (Parent))
+                               return false;
+
+                       if (IsExplicitImpl) {
+                               Expression expr = ExplicitInterfaceName.GetTypeExpression (Location);
+                               TypeExpr iface_texpr = expr.ResolveAsTypeTerminal (ec);
+                               if (iface_texpr == null)
+                                       return false;
+
+                               InterfaceType = iface_texpr.Type;
+
+                               if (!InterfaceType.IsInterface) {
+                                       Report.Error (538, Location, "'{0}' in explicit interface declaration is not an interface", TypeManager.CSharpName (InterfaceType));
+                                       return false;
+                               }
+
+                               if (!Parent.VerifyImplements (InterfaceType, ShortName, Name, Location))
+                                       return false;
+                               
+                               Modifiers.Check (Modifiers.AllowedExplicitImplFlags, explicit_mod_flags, 0, Location);
+                       }
+
+                       return true;
+               }
+
+               /// <summary>
+               /// The name of the member can be changed during definition (see IndexerName attribute)
+               /// </summary>
+               protected virtual void UpdateMemberName ()
+               {
+                       MemberName.Name = ShortName;
+               }
+
+               public override string GetSignatureForError (TypeContainer tc)
+               {
+                       return String.Concat (tc.Name, '.', base.GetSignatureForError (tc));
+               }
+
+               protected bool IsTypePermitted ()
+               {
+                       if (MemberType == TypeManager.arg_iterator_type || MemberType == TypeManager.typed_reference_type) {
+                               Report.Error (610, Location, "Field or property cannot be of type '{0}'", TypeManager.CSharpName (MemberType));
+                               return false;
+                       }
+                       return true;
+               }
+
+               protected override bool VerifyClsCompliance(DeclSpace ds)
+               {
+                       if (base.VerifyClsCompliance (ds)) {
+                               return true;
+                       }
+
+                       if (IsInterface && HasClsCompliantAttribute && ds.IsClsCompliaceRequired (ds)) {
+                               Report.Error (3010, Location, "'{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError ());
+                       }
+                       return false;
+               }
+
+               protected override void VerifyObsoleteAttribute()
+               {
+                       CheckUsageOfObsoleteAttribute (MemberType);
+               }
+       }
+
+       //
+       // Fields and Events both generate FieldBuilders, we use this to share 
+       // their common bits.  This is also used to flag usage of the field
+       //
+       abstract public class FieldBase : MemberBase {
+               public FieldBuilder  FieldBuilder;
+               public Status status;
+
+               [Flags]
+               public enum Status : byte {
+                       ASSIGNED = 1,
+                       USED = 2,
+                       HAS_OFFSET = 4          // Used by FieldMember.
+               }
+
+               static string[] attribute_targets = new string [] { "field" };
+
+               /// <summary>
+               ///  Symbol with same name in parent class/struct
+               /// </summary>
+               public MemberInfo conflict_symbol;
+
+               //
+               // The constructor is only exposed to our children
+               //
+               protected FieldBase (TypeContainer parent, Expression type, int mod,
+                                    int allowed_mod, MemberName name, object init,
+                                    Attributes attrs, Location loc)
+                       : base (parent, type, mod, allowed_mod, Modifiers.PRIVATE,
+                               name, attrs, loc)
+               {
+                       this.init = init;
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Field;
+                       }
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type == TypeManager.marshal_as_attr_type) {
+                               UnmanagedMarshal marshal = a.GetMarshal (this);
+                               if (marshal != null) {
+                                       FieldBuilder.SetMarshal (marshal);
+                               }
+                                       return;
+                               }
+
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
+                               a.Error_InvalidSecurityParent ();
+                               return;
+                       }
+
+                       FieldBuilder.SetCustomAttribute (cb);
+               }
+
+               //
+               // Whether this field has an initializer.
+               //
+               public bool HasInitializer {
+                       get {
+                               return init != null;
+                       }
+               }
+
+               protected readonly Object init;
+               // Private.
+               Expression init_expr;
+               bool init_expr_initialized = false;
+
+               protected override bool CheckGenericOverride (MethodInfo method, string name)
+               {
+                       return true;
+               }
+
+               //
+               // Resolves and returns the field initializer.
+               //
+               public Expression GetInitializerExpression (EmitContext ec)
+               {
+                       if (init_expr_initialized)
+                               return init_expr;
+
+                       Expression e;
+                       if (init is Expression)
+                               e = (Expression) init;
+                       else
+                               e = new ArrayCreation (Type, "", (ArrayList)init, Location);
+
+                       ec.IsFieldInitializer = true;
+                       e = e.DoResolve (ec);
+                       ec.IsFieldInitializer = false;
+
+                       init_expr = e;
+                       init_expr_initialized = true;
+
+                       return init_expr;
+               }
+
+               protected override bool CheckBase ()
+               {
+                       if (!base.CheckBase ())
+                               return false;
+
+                       // TODO: Implement
+                       if (IsInterface)
+                               return true;
+
+                       conflict_symbol = Parent.FindMemberWithSameName (Name, false);
+                       if (conflict_symbol == null) {
+                               if ((RootContext.WarningLevel >= 4) && ((ModFlags & Modifiers.NEW) != 0)) {
+                                       Report.Warning (109, Location, "The member '{0}' does not hide an inherited member. The new keyword is not required", GetSignatureForError (Parent));
+                               }
+                               return true;
+                       }
+
+                       if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE)) == 0) {
+                               Report.SymbolRelatedToPreviousError (conflict_symbol);
+                               Report.Warning (108, Location, "The keyword new is required on '{0}' because it hides inherited member", GetSignatureForError (Parent));
+                       }
+
+                       return true;
+               }
+
+               protected override bool DoDefine (DeclSpace ds)
+               {
+                       if (!base.DoDefine (ds))
+                               return false;
+
+                       if (MemberType == TypeManager.void_type) {
+                               Report.Error (1547, Location,
+                                             "Keyword 'void' cannot be used in this context");
+                               return false;
+                       }
+                       return true;
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       if (FieldBuilder == null) {
+                               return base.GetSignatureForError (Parent);
+                       }
+                       return TypeManager.GetFullNameSignature (FieldBuilder);
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+
+               protected override bool VerifyClsCompliance (DeclSpace ds)
+               {
+                       if (!base.VerifyClsCompliance (ds))
+                               return false;
+
+                       if (FieldBuilder == null) {
+                               return true;
+                       }
+
+                       if (!AttributeTester.IsClsCompliant (FieldBuilder.FieldType)) {
+                               Report.Error (3003, Location, "Type of '{0}' is not CLS-compliant", GetSignatureForError ());
+                       }
+                       return true;
+               }
+
+
+               public void SetAssigned ()
+               {
+                       status |= Status.ASSIGNED;
+               }
+       }
+
+       public abstract class FieldMember: FieldBase
+       {
+               
+
+               protected FieldMember (TypeContainer parent, Expression type, int mod,
+                       int allowed_mod, MemberName name, object init, Attributes attrs, Location loc)
+                       : base (parent, type, mod, allowed_mod, name, init, attrs, loc)
+               {
+               }
+
+               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type == TypeManager.field_offset_attribute_type)
+                       {
+                               status |= Status.HAS_OFFSET;
+
+                               if (!Parent.HasExplicitLayout) {
+                                       Report.Error (636, Location, "The FieldOffset attribute can only be placed on members of types marked with the StructLayout(LayoutKind.Explicit)");
+                                       return;
+                               }
+
+                               if ((ModFlags & Modifiers.STATIC) != 0 || this is Const) {
+                                       Report.Error (637, Location, "The FieldOffset attribute is not allowed on static or const fields");
+                                       return;
+                               }
+                       }
+                       base.ApplyAttributeBuilder (a, cb);
+               }
+
+
+               public override bool Define()
+               {
+                       EmitContext ec = Parent.EmitContext;
+                       if (ec == null)
+                               throw new InternalErrorException ("FieldMember.Define called too early");
+
+                       bool old_unsafe = ec.InUnsafe;
+                       ec.InUnsafe = InUnsafe;
+                       TypeExpr texpr = Type.ResolveAsTypeTerminal (ec);
+                       ec.InUnsafe = old_unsafe;
+                       if (texpr == null)
+                               return false;
+                       
+                       MemberType = texpr.Type;
+
+                       if (!CheckBase ())
+                               return false;
+                       
+                       if (!Parent.AsAccessible (MemberType, ModFlags)) {
+                               Report.Error (52, Location,
+                                       "Inconsistent accessibility: field type `" +
+                                       TypeManager.CSharpName (MemberType) + "' is less " +
+                                       "accessible than field `" + Name + "'");
+                               return false;
+                       }
+
+                       if (!IsTypePermitted ())
+                               return false;
+
+                       if (MemberType.IsPointer && !UnsafeOK (Parent))
+                               return false;
+
+                       return true;
+               }
+
+               public override void Emit ()
+               {
+                       if (Parent.HasExplicitLayout && ((status & Status.HAS_OFFSET) == 0) && (ModFlags & Modifiers.STATIC) == 0) {
+                               Report.Error (625, Location, "'{0}': Instance field types marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset attribute.", GetSignatureForError ());
+                       }
+
+                       base.Emit ();
+               }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "F:"; }
+               }
+       }
+
+       //
+       // The Field class is used to represents class/struct fields during parsing.
+       //
+       public class Field : FieldMember {
+               // <summary>
+               //   Modifiers allowed in a class declaration
+               // </summary>
+               const int AllowedModifiers =
+                       Modifiers.NEW |
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE |
+                       Modifiers.STATIC |
+                       Modifiers.VOLATILE |
+                       Modifiers.UNSAFE |
+                       Modifiers.READONLY;
+
+               public Field (TypeContainer parent, Expression type, int mod, string name,
+                             Object expr_or_array_init, Attributes attrs, Location loc)
+                       : base (parent, type, mod, AllowedModifiers, new MemberName (name),
+                               expr_or_array_init, attrs, loc)
+               {
+               }
+
+               public override bool Define ()
+               {
+                       if (!base.Define ())
+                               return false;
+
+                       if (RootContext.WarningLevel > 1){
+                               Type ptype = Parent.TypeBuilder.BaseType;
+
+                               // ptype is only null for System.Object while compiling corlib.
+                               if (ptype != null){
+                                       TypeContainer.FindMembers (
+                                               ptype, MemberTypes.Method,
+                                               BindingFlags.Public |
+                                               BindingFlags.Static | BindingFlags.Instance,
+                                               System.Type.FilterName, Name);
+                               }
+                       }
+
+                       if ((ModFlags & Modifiers.VOLATILE) != 0){
+                               if (!MemberType.IsClass){
+                                       Type vt = MemberType;
+                                       
+                                       if (TypeManager.IsEnumType (vt))
+                                               vt = TypeManager.EnumToUnderlying (MemberType);
+
+                                       if (!((vt == TypeManager.bool_type) ||
+                                             (vt == TypeManager.sbyte_type) ||
+                                             (vt == TypeManager.byte_type) ||
+                                             (vt == TypeManager.short_type) ||
+                                             (vt == TypeManager.ushort_type) ||
+                                             (vt == TypeManager.int32_type) ||
+                                             (vt == TypeManager.uint32_type) ||    
+                                             (vt == TypeManager.char_type) ||
+                                             (vt == TypeManager.float_type) ||
+                                             (!vt.IsValueType))){
+                                               Report.Error (
+                                                       677, Location, Parent.MakeName (Name) +
+                                                       " A volatile field can not be of type `" +
+                                                       TypeManager.CSharpName (vt) + "'");
+                                               return false;
+                                       }
+                               }
+
+                               if ((ModFlags & Modifiers.READONLY) != 0){
+                                       Report.Error (
+                                                     678, Location,
+                                                     "A field can not be both volatile and readonly");
+                                       return false;
+                               }
+                       }
+
+                       FieldAttributes fa = Modifiers.FieldAttr (ModFlags);
+
+                       if (Parent.Kind == Kind.Struct && 
+                           ((fa & FieldAttributes.Static) == 0) &&
+                           MemberType == Parent.TypeBuilder &&
+                           !TypeManager.IsBuiltinType (MemberType)){
+                               Report.Error (523, Location, "Struct member `" + Parent.Name + "." + Name + 
+                                             "' causes a cycle in the structure layout");
+                               return false;
+                       }
+
+                       try {
+                               FieldBuilder = Parent.TypeBuilder.DefineField (
+                                       Name, MemberType, Modifiers.FieldAttr (ModFlags));
+
+                       TypeManager.RegisterFieldBase (FieldBuilder, this);
+                       }
+                       catch (ArgumentException) {
+                               Report.Warning (-24, Location, "The Microsoft runtime is unable to use [void|void*] as a field type, try using the Mono runtime.");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               public override void Emit ()
+               {
+                       if (OptAttributes != null) {
+                               EmitContext ec = new EmitContext (
+                                       Parent, Location, null, FieldBuilder.FieldType,
+                                       ModFlags);
+                               OptAttributes.Emit (ec, this);
+               }
+
+                       base.Emit ();
+               }
+       }
+
+       //
+       // `set' and `get' accessors are represented with an Accessor.
+       // 
+       public class Accessor {
+               //
+               // Null if the accessor is empty, or a Block if not
+               //
+               public const int AllowedModifiers = 
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE;
+               
+               public ToplevelBlock Block;
+               public Attributes Attributes;
+               public Location Location;
+               public int ModFlags;
+               
+               public Accessor (ToplevelBlock b, int mod, Attributes attrs, Location loc)
+               {
+                       Block = b;
+                       Attributes = attrs;
+                       Location = loc;
+                       ModFlags = Modifiers.Check (AllowedModifiers, mod, 0, loc);
+               }
+       }
+
+
+       // Ooouh Martin, templates are missing here.
+       // When it will be possible move here a lot of child code and template method type.
+       public abstract class AbstractPropertyEventMethod: MemberCore, IMethodData {
+               protected MethodData method_data;
+               protected ToplevelBlock block;
+               protected ListDictionary declarative_security;
+
+               // The accessor are created event if they are not wanted.
+               // But we need them because their names are reserved.
+               // Field says whether accessor will be emited or not
+               public readonly bool IsDummy;
+
+               protected readonly string prefix;
+
+               ReturnParameter return_attributes;
+
+               public AbstractPropertyEventMethod (MemberBase member, string prefix)
+                       : base (null, SetupName (prefix, member), null, member.Location)
+               {
+                       this.prefix = prefix;
+                       IsDummy = true;
+               }
+
+               public AbstractPropertyEventMethod (MemberBase member, Accessor accessor,
+                                                   string prefix)
+                       : base (null, SetupName (prefix, member),
+                               accessor.Attributes, accessor.Location)
+               {
+                       this.prefix = prefix;
+                       this.block = accessor.Block;
+               }
+
+               static MemberName SetupName (string prefix, MemberBase member)
+               {
+                       MemberName name = member.MemberName.Clone ();
+                       name.Name = prefix + member.ShortName;
+                       return name;
+               }
+
+               public void UpdateName (MemberBase member)
+               {
+                       MemberName.Name = prefix + member.ShortName;
+               }
+
+               #region IMethodData Members
+
+               public ToplevelBlock Block {
+                       get {
+                               return block;
+                       }
+
+                       set {
+                               block = value;
+                       }
+               }
+
+               public CallingConventions CallingConventions {
+                       get {
+                               return CallingConventions.Standard;
+                       }
+               }
+
+               public bool IsExcluded (EmitContext ec)
+               {
+                       return false;
+               }
+
+               GenericMethod IMethodData.GenericMethod {
+                       get {
+                               return null;
+                       }
+               }
+
+               public MemberName MethodName {
+                       get {
+                               return MemberName;
+                       }
+               }
+
+               public abstract ObsoleteAttribute GetObsoleteAttribute ();
+               public abstract Type[] ParameterTypes { get; }
+               public abstract Type ReturnType { get; }
+               public abstract EmitContext CreateEmitContext(TypeContainer tc, ILGenerator ig);
+
+               #endregion
+
+               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type == TypeManager.cls_compliant_attribute_type || a.Type == TypeManager.obsolete_attribute_type ||
+                                       a.Type == TypeManager.conditional_attribute_type) {
+                               Report.Error (1667, a.Location, "'{0}' is not valid on property or event accessors. It is valid on {1} declarations only", TypeManager.CSharpName (a.Type), a.GetValidTargets ());
+                               return;
+                       }
+
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (false)) {
+                               if (declarative_security == null)
+                                       declarative_security = new ListDictionary ();
+                               a.ExtractSecurityPermissionSet (declarative_security);
+                               return;
+                       }
+
+                       if (a.Target == AttributeTargets.Method) {
+                               method_data.MethodBuilder.SetCustomAttribute (cb);
+                               return;
+                       }
+
+                       if (a.Target == AttributeTargets.ReturnValue) {
+                               if (return_attributes == null)
+                                       return_attributes = new ReturnParameter (method_data.MethodBuilder, Location);
+
+                               return_attributes.ApplyAttributeBuilder (a, cb);
+                               return;
+                       }
+
+                       ApplyToExtraTarget (a, cb);
+               }
+
+               virtual protected void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb)
+               {
+                       System.Diagnostics.Debug.Fail ("You forgot to define special attribute target handling");
+               }
+
+               public override bool Define()
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public virtual void Emit (TypeContainer container)
+               {
+                       method_data.Emit (container, this);
+
+                       if (declarative_security != null) {
+                               foreach (DictionaryEntry de in declarative_security) {
+                                       method_data.MethodBuilder.AddDeclarativeSecurity ((SecurityAction)de.Key, (PermissionSet)de.Value);
+                               }
+                       }
+
+                       block = null;
+               }
+
+               public override bool IsClsCompliaceRequired(DeclSpace ds)
+               {
+                       return false;
+               }
+
+               public bool IsDuplicateImplementation (MethodCore method)
+               {
+                       if (Name != method.Name)
+                               return false;
+
+                       Type[] param_types = method.ParameterTypes;
+
+                       if (param_types.Length != ParameterTypes.Length)
+                               return false;
+
+                       for (int i = 0; i < param_types.Length; i++)
+                               if (param_types [i] != ParameterTypes [i])
+                                       return false;
+
+                       Report.SymbolRelatedToPreviousError (method);
+                       Report.Error (111, Location, "Type '{0}' already defines a member called '{1}' with " +
+                                     "the same parameter types", Parent.Name, Name);
+                       return true;
+               }
+
+               public new Location Location { 
+                       get {
+                               return base.Location;
+                       }
+               }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { throw new InvalidOperationException ("Unexpected attempt to get doc comment from " + this.GetType () + "."); }
+               }
+
+               protected override void VerifyObsoleteAttribute()
+               {
+               }
+
+       }
+
+       //
+       // Properties and Indexers both generate PropertyBuilders, we use this to share 
+       // their common bits.
+       //
+       abstract public class PropertyBase : MethodCore {
+
+               public class GetMethod: PropertyMethod
+               {
+                       static string[] attribute_targets = new string [] { "method", "return" };
+                       Parameters parameters;
+
+                       public GetMethod (MethodCore method):
+                               base (method, "get_")
+                       {
+                       }
+
+                       public GetMethod (MethodCore method, Accessor accessor):
+                               base (method, accessor, "get_")
+                       {
+                       }
+
+                       public GetMethod (MethodCore method, Parameters parameters):
+                               base (method, "get_")
+                       {
+                               this.parameters = parameters;
+                       }
+
+                       public GetMethod (MethodCore method, Accessor accessor, Parameters parameters):
+                               base (method, accessor, "get_")
+                       {
+                               this.parameters = parameters;
+                       }
+
+                       protected virtual InternalParameters GetParameterInfo (EmitContext ec)
+                       {
+                               if (parameters == null) {
+                                       Parameter [] parms = new Parameter [1];
+                                       parms [0] = new Parameter (method.Type, "Screwed", Parameter.Modifier.NONE, null);
+                                       parameters = new Parameters (parms, null, method.Location);
+                               }
+                               
+                               Type [] types = parameters.GetParameterInfo (ec);
+                               return new InternalParameters (types, parameters);
+                       }
+
+                       public override MethodBuilder Define(TypeContainer container)
+                       {
+                               base.Define (container);
+                               
+                               method_data = new MethodData (method, GetParameterInfo (container.EmitContext), ModFlags, flags, this);
+
+                               if (!method_data.Define (container))
+                                       return null;
+
+                               return method_data.MethodBuilder;
+                       }
+
+                       public override string GetSignatureForError (TypeContainer tc)
+                       {
+                               return String.Concat (base.GetSignatureForError (tc), ".get");
+                       }
+
+                       public override Type ReturnType {
+                               get {
+                                       return method.MemberType;
+                               }
+                       }
+
+                       public override string[] ValidAttributeTargets {
+                               get {
+                                       return attribute_targets;
+                               }
+                       }
+               }
+
+               public class SetMethod: PropertyMethod {
+
+                       static string[] attribute_targets = new string [] { "method", "param", "return" };
+                       ImplicitParameter param_attr;
+
+                       Parameters parameters;
+
+                       public SetMethod (MethodCore method):
+                               base (method, "set_")
+                       {
+                       }
+
+                       public SetMethod (MethodCore method, Accessor accessor):
+                               base (method, accessor, "set_")
+                       {
+                       }
+
+                       public SetMethod (MethodCore method, Parameters parameters):
+                               base (method, "set_")
+                       {
+                               this.parameters = parameters;
+                       }
+
+                       public SetMethod (MethodCore method, Accessor accessor, Parameters parameters):
+                               base (method, accessor, "set_")
+                       {
+                               this.parameters = parameters;
+                       }
+                       protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
+                       {
+                               if (a.Target == AttributeTargets.Parameter) {
+                                       if (param_attr == null)
+                                               param_attr = new ImplicitParameter (method_data.MethodBuilder);
+
+                                       param_attr.ApplyAttributeBuilder (a, cb);
+                                       return;
+                               }
+
+                               base.ApplyAttributeBuilder (a, cb);
+                       }
+
+                       protected virtual InternalParameters GetParameterInfo (EmitContext ec)
+                       {
+
+                               if (parameters == null) {
+                                       Parameter [] parms = new Parameter [1];
+                                       parms [0] = new Parameter (method.Type, "value", Parameter.Modifier.NONE, null);
+                                       parameters = new Parameters (parms, null, method.Location);
+                               }
+                               
+                               Type [] types = parameters.GetParameterInfo (ec);
+
+                               return new InternalParameters (types, parameters);
+                       }
+
+                       public override MethodBuilder Define(TypeContainer container)
+                       {
+                               if (container.EmitContext == null)
+                                       throw new InternalErrorException ("SetMethod.Define called too early");
+                                       
+                               base.Define (container);
+                               
+                               method_data = new MethodData (method, GetParameterInfo (container.EmitContext), ModFlags, flags, this);
+
+                               if (!method_data.Define (container))
+                                       return null;
+
+                               return method_data.MethodBuilder;
+                       }
+
+                       public override string GetSignatureForError (TypeContainer tc)
+                       {
+                               return String.Concat (base.GetSignatureForError (tc), ".set");
+                       }
+
+                       public override Type[] ParameterTypes {
+                               get {
+                                       return new Type[] { method.MemberType };
+                               }
+                       }
+
+                       public override Type ReturnType {
+                               get {
+                                       return TypeManager.void_type;
+                               }
+                       }
+
+                       public override string[] ValidAttributeTargets {
+                               get {
+                                       return attribute_targets;
+                               }
+                       }
+               }
+
+               static string[] attribute_targets = new string [] { "property" };
+
+               public abstract class PropertyMethod: AbstractPropertyEventMethod {
+                       protected readonly MethodCore method;
+                       protected MethodAttributes flags;
+
+                       public PropertyMethod (MethodCore method, string prefix)
+                               : base (method, prefix)
+                       {
+                               this.method = method;
+                       }
+
+                       public PropertyMethod (MethodCore method, Accessor accessor, string prefix)
+                               : base (method, accessor, prefix)
+                       {
+                               this.method = method;
+                               this.ModFlags = accessor.ModFlags;
+
+                               if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
+                                       Report.FeatureIsNotStandardized (Location, "accessor modifiers");
+                                       Environment.Exit (1);
+                               }
+                       }
+
+                       public override AttributeTargets AttributeTargets {
+                               get {
+                                       return AttributeTargets.Method;
+                               }
+                       }
+
+                       public override bool IsClsCompliaceRequired(DeclSpace ds)
+                       {
+                               return method.IsClsCompliaceRequired (ds);
+                       }
+
+                       public InternalParameters ParameterInfo 
+                       {
+                               get {
+                                       return method_data.ParameterInfo;
+                               }
+                       }
+
+                       public virtual MethodBuilder Define (TypeContainer container)
+                       {
+                               //
+                               // Check for custom access modifier
+                               //
+                                if (ModFlags == 0) {
+                                        ModFlags = method.ModFlags;
+                                        flags = method.flags;
+                                } else {
+                                       CheckModifiers (container, ModFlags);
+                                       ModFlags |= (method.ModFlags & (~Modifiers.Accessibility));
+                                       flags = Modifiers.MethodAttr (ModFlags);
+                                       flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
+                               }
+
+                               return null;
+
+                       }
+
+                       public override Type[] ParameterTypes {
+                               get {
+                                       return TypeManager.NoTypes;
+                               }
+                       }
+
+                       public override EmitContext CreateEmitContext (TypeContainer tc,
+                                                                      ILGenerator ig)
+                       {
+                               return new EmitContext (
+                                       tc, method.ds, method.Location, ig, ReturnType,
+                                       method.ModFlags, false);
+                       }
+
+                       public override ObsoleteAttribute GetObsoleteAttribute ()
+                       {
+                               return method.GetObsoleteAttribute (method.ds);
+                       }
+
+                       public override string GetSignatureForError (TypeContainer tc)
+                       {
+                               return String.Concat (tc.Name, '.', method.Name);
+                       }
+
+                       void CheckModifiers (TypeContainer container, int modflags)
+                        {
+                                int flags = 0;
+                                int mflags = method.ModFlags & Modifiers.Accessibility;
+
+                                if ((mflags & Modifiers.PUBLIC) != 0) {
+                                        flags |= Modifiers.PROTECTED | Modifiers.INTERNAL | Modifiers.PRIVATE;
+                                }
+                                else if ((mflags & Modifiers.PROTECTED) != 0) {
+                                        if ((mflags & Modifiers.INTERNAL) != 0)
+                                                flags |= Modifiers.PROTECTED | Modifiers.INTERNAL;
+
+                                        flags |= Modifiers.PRIVATE;
+                                }
+                                else if ((mflags & Modifiers.INTERNAL) != 0)
+                                        flags |= Modifiers.PRIVATE;
+
+                                if ((mflags == modflags) || (modflags & (~flags)) != 0)
+                                        Report.Error (273, Location, "{0}: accessibility modifier must be more restrictive than the property or indexer",
+                                                       GetSignatureForError (container));
+                        }
+               }
+
+               public PropertyMethod Get, Set;
+               public PropertyBuilder PropertyBuilder;
+               public MethodBuilder GetBuilder, SetBuilder;
+
+               protected EmitContext ec;
+
+               public PropertyBase (TypeContainer parent, Expression type, int mod_flags,
+                                    int allowed_mod, bool is_iface, MemberName name,
+                                    Parameters parameters, Attributes attrs,
+                                    Location loc)
+                       : base (parent, null, type, mod_flags, allowed_mod, is_iface, name,
+                               attrs, parameters, loc)
+               {
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
+                               a.Error_InvalidSecurityParent ();
+                               return;
+                       }
+
+                       PropertyBuilder.SetCustomAttribute (cb);
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Property;
+                       }
+               }
+
+               public override bool Define ()
+               {
+                       if (!DoDefine (Parent))
+                               return false;
+
+                       if (!IsTypePermitted ())
+                               return false;
+
+                       return true;
+               }
+
+               protected override bool DoDefine (DeclSpace ds)
+               {
+                       if (!base.DoDefine (ds))
+                               return false;
+
+                       //
+                       // Accessors modifiers check
+                       //
+
+                       if (Get.ModFlags != 0 && Set.ModFlags != 0) {
+                               Report.Error (274, Location, "'{0}': cannot specify accessibility modifiers for both accessors of the property or indexer.",
+                                               GetSignatureForError ());
+                               return false;
+                       }
+
+                       if ((Get.IsDummy || Set.IsDummy)
+                                       && (Get.ModFlags != 0 || Set.ModFlags != 0) && (ModFlags & Modifiers.OVERRIDE) == 0) {
+                               Report.Error (276, Location, 
+                                       "'{0}': accessibility modifiers on accessors may only be used if the property or indexer has both a get and a set accessor.",
+                                       GetSignatureForError ());
+                               return false;
+                       }
+
+                       if (MemberType.IsAbstract && MemberType.IsSealed) {
+                               Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
+                               return false;
+                       }
+
+                       ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
+                       return true;
+               }
+
+               public override string GetSignatureForError()
+               {
+                       if (PropertyBuilder == null)
+                               return GetSignatureForError (Parent);
+
+                       return TypeManager.CSharpSignature (PropertyBuilder, false);
+               }
+
+
+               protected override bool CheckForDuplications ()
+               {
+                       ArrayList ar = Parent.Indexers;
+                       if (ar != null) {
+                               int arLen = ar.Count;
+                                       
+                               for (int i = 0; i < arLen; i++) {
+                                       Indexer m = (Indexer) ar [i];
+                                       if (IsDuplicateImplementation (m))
+                                               return false;
+                               }
+                       }
+
+                       ar = Parent.Properties;
+                       if (ar != null) {
+                               int arLen = ar.Count;
+                                       
+                               for (int i = 0; i < arLen; i++) {
+                                       Property m = (Property) ar [i];
+                                       if (IsDuplicateImplementation (m))
+                                               return false;
+                               }
+                       }
+
+                       return true;
+               }
+
+               // TODO: rename to Resolve......
+               protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
+               {
+                       PropertyInfo parent_property = container.ParentCache.FindMemberToOverride (
+                               container.TypeBuilder, Name, ParameterTypes, true) as PropertyInfo;
+
+                       if (parent_property == null)
+                               return null;
+
+                       parent_ret_type = parent_property.PropertyType;
+                       MethodInfo get_accessor = parent_property.GetGetMethod (true);
+                       MethodInfo set_accessor = parent_property.GetSetMethod (true);
+                       MethodAttributes get_accessor_access, set_accessor_access;
+
+                       if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+                               if (Get != null && !Get.IsDummy && get_accessor == null) {
+                                       Report.SymbolRelatedToPreviousError (parent_property);
+                                       Report.Error (545, Location, "'{0}': cannot override because '{1}' does not have an overridable get accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
+                               }
+
+                               if (Set != null && !Set.IsDummy && set_accessor == null) {
+                                       Report.SymbolRelatedToPreviousError (parent_property);
+                                       Report.Error (546, Location, "'{0}': cannot override because '{1}' does not have an overridable set accessor", GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
+                               }
+                       }
+                       
+                       //
+                       // Check parent accessors access
+                       //
+                       get_accessor_access = set_accessor_access = 0;
+                       if ((ModFlags & Modifiers.NEW) == 0) {
+                               if (get_accessor != null) {
+                                       MethodAttributes get_flags = Modifiers.MethodAttr (Get.ModFlags != 0 ? Get.ModFlags : ModFlags);
+                                       get_accessor_access = (get_accessor.Attributes & MethodAttributes.MemberAccessMask);
+
+                                       if (!Get.IsDummy && !CheckAccessModifiers (get_flags & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
+                                               Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
+                                                               GetSignatureForError (), TypeManager.GetFullNameSignature (parent_property));
+                               }
+
+                               if (set_accessor != null)  {
+                                       MethodAttributes set_flags = Modifiers.MethodAttr (Set.ModFlags != 0 ? Set.ModFlags : ModFlags);
+                                       set_accessor_access = (set_accessor.Attributes & MethodAttributes.MemberAccessMask);
+
+                                       if (!Set.IsDummy && !CheckAccessModifiers (set_flags & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
+                                               Report.Error (507, Location, "'{0}' can't change the access modifiers when overriding inherited member '{1}'",
+                                                               GetSignatureForError (container), TypeManager.GetFullNameSignature (parent_property));
+                               }
+                       }
+
+                       //
+                       // Get the less restrictive access
+                       //
+                       return get_accessor_access > set_accessor_access ? get_accessor : set_accessor;
+               }
+
+               public override void Emit ()
+               {
+                       //
+                       // The PropertyBuilder can be null for explicit implementations, in that
+                       // case, we do not actually emit the ".property", so there is nowhere to
+                       // put the attribute
+                       //
+                       if (PropertyBuilder != null && OptAttributes != null)
+                               OptAttributes.Emit (ec, this);
+
+                       if (!Get.IsDummy)
+                               Get.Emit (Parent);
+
+                       if (!Set.IsDummy)
+                               Set.Emit (Parent);
+
+                       base.Emit ();
+               }
+
+               /// <summary>
+               /// Tests whether accessors are not in collision with some method (CS0111)
+               /// </summary>
+               public bool AreAccessorsDuplicateImplementation (MethodCore mc)
+               {
+                       return Get.IsDuplicateImplementation (mc) || Set.IsDuplicateImplementation (mc);
+               }
+
+               protected override void UpdateMemberName ()
+               {
+                       base.UpdateMemberName ();
+
+                       Get.UpdateName (this);
+                       Set.UpdateName (this);
+               }
+
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "P:"; }
+               }
+       }
+                       
+       public class Property : PropertyBase, IIteratorContainer {
+               const int AllowedModifiers =
+                       Modifiers.NEW |
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE |
+                       Modifiers.STATIC |
+                       Modifiers.SEALED |
+                       Modifiers.OVERRIDE |
+                       Modifiers.ABSTRACT |
+                       Modifiers.UNSAFE |
+                       Modifiers.EXTERN |
+                       Modifiers.METHOD_YIELDS |
+                       Modifiers.VIRTUAL;
+
+               const int AllowedInterfaceModifiers =
+                       Modifiers.NEW;
+
+               public Property (TypeContainer parent, Expression type, int mod_flags,
+                                bool is_iface, MemberName name, Attributes attrs,
+                                Accessor get_block, Accessor set_block, Location loc)
+                       : base (parent, type, mod_flags,
+                               is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+                               is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
+                               loc)
+               {
+                       if (get_block == null)
+                               Get = new GetMethod (this);
+                       else
+                               Get = new GetMethod (this, get_block);
+
+                       if (set_block == null)
+                               Set = new SetMethod (this);
+                       else
+                               Set = new SetMethod (this, set_block);
+               }
+
+               public Property (TypeContainer ds, Expression type, int mod, bool is_iface,
+                                MemberName name, Attributes attrs, Parameters get_params, Accessor get_block,
+                                Parameters set_params, Accessor set_block, Location loc)
+                       : base (ds, type, mod,
+                               is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+                               is_iface, name, Parameters.EmptyReadOnlyParameters, attrs,
+                               loc)
+               {
+                       if (get_block == null)
+                               Get = new GetMethod (this, get_params);
+                       else
+                               Get = new GetMethod (this, get_block, get_params);
+
+                       if (set_block == null)
+                               Set = new SetMethod (this, set_params);
+                       else
+                               Set = new SetMethod (this, set_block, set_params);
+               }
+
+               public override bool Define ()
+               {
+                       if (!DoDefineBase ())
+                               return false;
+
+                       if (!base.Define ())
+                               return false;
+
+                       if (!CheckBase ())
+                               return false;
+
+                       flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
+
+                       if (!Get.IsDummy) {
+
+                               GetBuilder = Get.Define (Parent);
+                               if (GetBuilder == null)
+                                       return false;
+
+                               //
+                               // Setup iterator if we are one
+                               //
+                               if ((ModFlags & Modifiers.METHOD_YIELDS) != 0){
+                                       Iterator iterator = new Iterator (
+                                               Parent, "get", MemberType,
+                                               TypeManager.NoTypes, Get.ParameterInfo,
+                                               ModFlags, Get.Block, Location);
+                                       
+                                       if (!iterator.DefineIterator ())
+                                               return false;
+                                       Get.Block = iterator.Block;
+                               }
+                       }
+
+                       if (!Set.IsDummy) {
+                               SetBuilder = Set.Define (Parent);
+                               if (SetBuilder == null)
+                                       return false;
+
+                               SetBuilder.DefineParameter (1, ParameterAttributes.None, "value"); 
+                       }
+
+                       // FIXME - PropertyAttributes.HasDefault ?
+                       
+                       PropertyAttributes prop_attr = PropertyAttributes.None;
+                       if (!IsInterface)
+                               prop_attr |= PropertyAttributes.RTSpecialName |
+                       PropertyAttributes.SpecialName;
+
+                               PropertyBuilder = Parent.TypeBuilder.DefineProperty (
+                                       Name, prop_attr, MemberType, null);
+                               
+                               if (!Get.IsDummy)
+                                       PropertyBuilder.SetGetMethod (GetBuilder);
+                               
+                               if (!Set.IsDummy)
+                                       PropertyBuilder.SetSetMethod (SetBuilder);
+
+                               TypeManager.RegisterProperty (PropertyBuilder, GetBuilder, SetBuilder);
+                       return true;
+               }
+
+               public void SetYields ()
+               {
+                       ModFlags |= Modifiers.METHOD_YIELDS;
+               }
+       }
+
+       /// </summary>
+       ///  Gigantic workaround  for lameness in SRE follows :
+       ///  This class derives from EventInfo and attempts to basically
+       ///  wrap around the EventBuilder so that FindMembers can quickly
+       ///  return this in it search for members
+       /// </summary>
+       public class MyEventBuilder : EventInfo {
+               
+               //
+               // We use this to "point" to our Builder which is
+               // not really a MemberInfo
+               //
+               EventBuilder MyBuilder;
+               
+               //
+               // We "catch" and wrap these methods
+               //
+               MethodInfo raise, remove, add;
+
+               EventAttributes attributes;
+               Type declaring_type, reflected_type, event_type;
+               string name;
+
+               Event my_event;
+
+               public MyEventBuilder (Event ev, TypeBuilder type_builder, string name, EventAttributes event_attr, Type event_type)
+               {
+                       MyBuilder = type_builder.DefineEvent (name, event_attr, event_type);
+
+                       // And now store the values in our own fields.
+                       
+                       declaring_type = type_builder;
+
+                       reflected_type = type_builder;
+                       
+                       attributes = event_attr;
+                       this.name = name;
+                       my_event = ev;
+                       this.event_type = event_type;
+               }
+               
+               //
+               // Methods that you have to override.  Note that you only need 
+               // to "implement" the variants that take the argument (those are
+               // the "abstract" methods, the others (GetAddMethod()) are 
+               // regular.
+               //
+               public override MethodInfo GetAddMethod (bool nonPublic)
+               {
+                       return add;
+               }
+               
+               public override MethodInfo GetRemoveMethod (bool nonPublic)
+               {
+                       return remove;
+               }
+               
+               public override MethodInfo GetRaiseMethod (bool nonPublic)
+               {
+                       return raise;
+               }
+               
+               //
+               // These methods make "MyEventInfo" look like a Builder
+               //
+               public void SetRaiseMethod (MethodBuilder raiseMethod)
+               {
+                       raise = raiseMethod;
+                       MyBuilder.SetRaiseMethod (raiseMethod);
+               }
+
+               public void SetRemoveOnMethod (MethodBuilder removeMethod)
+               {
+                       remove = removeMethod;
+                       MyBuilder.SetRemoveOnMethod (removeMethod);
+               }
+
+               public void SetAddOnMethod (MethodBuilder addMethod)
+               {
+                       add = addMethod;
+                       MyBuilder.SetAddOnMethod (addMethod);
+               }
+
+               public void SetCustomAttribute (CustomAttributeBuilder cb)
+               {
+                       MyBuilder.SetCustomAttribute (cb);
+               }
+               
+               public override object [] GetCustomAttributes (bool inherit)
+               {
+                       // FIXME : There's nothing which can be seemingly done here because
+                       // we have no way of getting at the custom attribute objects of the
+                       // EventBuilder !
+                       return null;
+               }
+
+               public override object [] GetCustomAttributes (Type t, bool inherit)
+               {
+                       // FIXME : Same here !
+                       return null;
+               }
+
+               public override bool IsDefined (Type t, bool b)
+               {
+                       return true;
+               }
+
+               public override EventAttributes Attributes {
+                       get {
+                               return attributes;
+                       }
+               }
+
+               public override string Name {
+                       get {
+                               return name;
+                       }
+               }
+
+               public override Type DeclaringType {
+                       get {
+                               return declaring_type;
+                       }
+               }
+
+               public override Type ReflectedType {
+                       get {
+                               return reflected_type;
+                       }
+               }
+
+               public Type EventType {
+                       get {
+                               return event_type;
+                       }
+               }
+               
+               public void SetUsed ()
+               {
+                       if (my_event != null)
+                               my_event.status = (FieldBase.Status.ASSIGNED | FieldBase.Status.USED);
+               }
+       }
+       
+       /// <summary>
+       /// For case when event is declared like property (with add and remove accessors).
+       /// </summary>
+       public class EventProperty: Event {
+
+               static string[] attribute_targets = new string [] { "event", "property" };
+
+               public EventProperty (TypeContainer parent, Expression type, int mod_flags,
+                                     bool is_iface, MemberName name, Object init,
+                                     Attributes attrs, Accessor add, Accessor remove,
+                                     Location loc)
+                       : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
+               {
+                       Add = new AddDelegateMethod (this, add);
+                       Remove = new RemoveDelegateMethod (this, remove);
+
+                       // For this event syntax we don't report error CS0067
+                       // because it is hard to do it.
+                       SetAssigned ();
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+       }
+
+       /// <summary>
+       /// Event is declared like field.
+       /// </summary>
+       public class EventField: Event {
+
+               static string[] attribute_targets = new string [] { "event", "field", "method" };
+               static string[] attribute_targets_interface = new string[] { "event", "method" };
+
+               public EventField (TypeContainer parent, Expression type, int mod_flags,
+                                  bool is_iface, MemberName name, Object init,
+                                  Attributes attrs, Location loc)
+                       : base (parent, type, mod_flags, is_iface, name, init, attrs, loc)
+               {
+                       Add = new AddDelegateMethod (this);
+                       Remove = new RemoveDelegateMethod (this);
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Target == AttributeTargets.Field) {
+                               FieldBuilder.SetCustomAttribute (cb);
+                               return;
+                       }
+
+                       if (a.Target == AttributeTargets.Method) {
+                               Add.ApplyAttributeBuilder (a, cb);
+                               Remove.ApplyAttributeBuilder (a, cb);
+                               return;
+                       }
+
+                       base.ApplyAttributeBuilder (a, cb);
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return IsInterface ? attribute_targets_interface : attribute_targets;
+                       }
+               }
+       }
+
+       public abstract class Event : FieldBase {
+
+               protected sealed class AddDelegateMethod: DelegateMethod
+               {
+
+                       public AddDelegateMethod (Event method):
+                               base (method, "add_")
+                       {
+                       }
+
+                       public AddDelegateMethod (Event method, Accessor accessor):
+                               base (method, accessor, "add_")
+                       {
+                       }
+
+                       protected override MethodInfo DelegateMethodInfo {
+                               get {
+                                       return TypeManager.delegate_combine_delegate_delegate;
+                               }
+                       }
+
+               }
+
+               protected sealed class RemoveDelegateMethod: DelegateMethod
+               {
+                       public RemoveDelegateMethod (Event method):
+                               base (method, "remove_")
+                       {
+                       }
+
+                       public RemoveDelegateMethod (Event method, Accessor accessor):
+                               base (method, accessor, "remove_")
+                       {
+                       }
+
+                       protected override MethodInfo DelegateMethodInfo {
+                               get {
+                                       return TypeManager.delegate_remove_delegate_delegate;
+                               }
+                       }
+
+               }
+
+               public abstract class DelegateMethod: AbstractPropertyEventMethod
+               {
+                       protected readonly Event method;
+                       ImplicitParameter param_attr;
+
+                       static string[] attribute_targets = new string [] { "method", "param", "return" };
+
+                       public DelegateMethod (Event method, string prefix)
+                               : base (method, prefix)
+                       {
+                               this.method = method;
+                       }
+
+                       public DelegateMethod (Event method, Accessor accessor, string prefix)
+                               : base (method, accessor, prefix)
+                       {
+                               this.method = method;
+                       }
+
+                       protected override void ApplyToExtraTarget(Attribute a, CustomAttributeBuilder cb)
+                       {
+                               if (a.Target == AttributeTargets.Parameter) {
+                                       if (param_attr == null)
+                                               param_attr = new ImplicitParameter (method_data.MethodBuilder);
+
+                                       param_attr.ApplyAttributeBuilder (a, cb);
+                                       return;
+                               }
+
+                               base.ApplyAttributeBuilder (a, cb);
+                       }
+
+                       public override AttributeTargets AttributeTargets {
+                               get {
+                                       return AttributeTargets.Method;
+                               }
+                       }
+
+                       public override bool IsClsCompliaceRequired(DeclSpace ds)
+                       {
+                               return method.IsClsCompliaceRequired (ds);
+                       }
+
+                       public MethodBuilder Define (TypeContainer container, InternalParameters ip)
+                       {
+                               method_data = new MethodData (method, ip, method.ModFlags,
+                                       method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
+
+                               if (!method_data.Define (container))
+                                       return null;
+
+                               MethodBuilder mb = method_data.MethodBuilder;
+                               mb.DefineParameter (1, ParameterAttributes.None, "value");
+                               return mb;
+                       }
+
+
+                       public override void Emit (TypeContainer tc)
+                       {
+                               if (block != null) {
+                                       base.Emit (tc);
+                                       return;
+                               }
+
+                               ILGenerator ig = method_data.MethodBuilder.GetILGenerator ();
+                               EmitContext ec = CreateEmitContext (tc, ig);
+                               FieldInfo field_info = (FieldInfo)method.FieldBuilder;
+
+                               method_data.MethodBuilder.SetImplementationFlags (MethodImplAttributes.Synchronized);
+                               if ((method.ModFlags & Modifiers.STATIC) != 0) {
+                                       ig.Emit (OpCodes.Ldsfld, field_info);
+                                       ig.Emit (OpCodes.Ldarg_0);
+                                       ig.Emit (OpCodes.Call, DelegateMethodInfo);
+                                       ig.Emit (OpCodes.Castclass, method.MemberType);
+                                       ig.Emit (OpCodes.Stsfld, field_info);
+                               } else {
+                                       ig.Emit (OpCodes.Ldarg_0);
+                                       ig.Emit (OpCodes.Ldarg_0);
+                                       ig.Emit (OpCodes.Ldfld, field_info);
+                                       ig.Emit (OpCodes.Ldarg_1);
+                                       ig.Emit (OpCodes.Call, DelegateMethodInfo);
+                                       ig.Emit (OpCodes.Castclass, method.MemberType);
+                                       ig.Emit (OpCodes.Stfld, field_info);
+                               }
+                               ig.Emit (OpCodes.Ret);
+                       }
+
+                       protected abstract MethodInfo DelegateMethodInfo { get; }
+
+                       public override Type[] ParameterTypes {
+                               get {
+                                       return new Type[] { method.MemberType };
+                               }
+                       }
+
+                       public override Type ReturnType {
+                               get {
+                                       return TypeManager.void_type;
+                               }
+                       }
+
+                       public override EmitContext CreateEmitContext (TypeContainer tc,
+                                                                      ILGenerator ig)
+                       {
+                               return new EmitContext (
+                                       tc, method.Parent, Location, ig, ReturnType,
+                                       method.ModFlags, false);
+                       }
+
+                       public override string GetSignatureForError (TypeContainer tc)
+                       {
+                               return String.Concat (tc.Name, '.', method.Name);
+                       }
+
+                       public override ObsoleteAttribute GetObsoleteAttribute ()
+                       {
+                               return method.GetObsoleteAttribute (method.Parent);
+                       }
+
+                       public override string[] ValidAttributeTargets {
+                               get {
+                                       return attribute_targets;
+                               }
+                       }
+               }
+
+
+               const int AllowedModifiers =
+                       Modifiers.NEW |
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE |
+                       Modifiers.STATIC |
+                       Modifiers.VIRTUAL |
+                       Modifiers.SEALED |
+                       Modifiers.OVERRIDE |
+                       Modifiers.UNSAFE |
+                       Modifiers.ABSTRACT;
+
+               const int AllowedInterfaceModifiers =
+                       Modifiers.NEW;
+
+               public DelegateMethod Add, Remove;
+               public MyEventBuilder     EventBuilder;
+               public MethodBuilder AddBuilder, RemoveBuilder;
+
+               MethodData AddData, RemoveData;
+               
+               public Event (TypeContainer parent, Expression type, int mod_flags,
+                             bool is_iface, MemberName name, Object init, Attributes attrs,
+                             Location loc)
+                       : base (parent, type, mod_flags,
+                               is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+                               name, init, attrs, loc)
+               {
+                       IsInterface = is_iface;
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
+                               a.Error_InvalidSecurityParent ();
+                               return;
+                       }
+                       
+                       EventBuilder.SetCustomAttribute (cb);
+               }
+
+               public bool AreAccessorsDuplicateImplementation (MethodCore mc)
+               {
+                       return Add.IsDuplicateImplementation (mc) || Remove.IsDuplicateImplementation (mc);
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Event;
+                       }
+               }
+  
+               public override bool Define ()
+               {
+                       EventAttributes e_attr;
+                       e_attr = EventAttributes.None;
+
+                       if (!DoDefineBase ())
+                               return false;
+
+                       if (!DoDefine (Parent))
+                               return false;
+
+                       if (init != null && ((ModFlags & Modifiers.ABSTRACT) != 0)){
+                               Report.Error (74, Location, "'" + Parent.Name + "." + Name +
+                                             "': abstract event can not have an initializer");
+                               return false;
+                       }
+
+                       if (!TypeManager.IsDelegateType (MemberType)) {
+                               Report.Error (66, Location, "'" + Parent.Name + "." + Name +
+                                             "' : event must be of a delegate type");
+                               return false;
+                       }
+
+                       EmitContext ec = Parent.EmitContext;
+                       if (ec == null)
+                               throw new InternalErrorException ("Event.Define called too early?");
+                       bool old_unsafe = ec.InUnsafe;
+                       ec.InUnsafe = InUnsafe;
+
+                       Parameter [] parms = new Parameter [1];
+                       parms [0] = new Parameter (Type, "value", Parameter.Modifier.NONE, null);
+                       Parameters parameters = new Parameters (parms, null, Location);
+                       Type [] types = parameters.GetParameterInfo (ec);
+                       InternalParameters ip = new InternalParameters (types, parameters);
+
+                       ec.InUnsafe = old_unsafe;
+
+                       if (!CheckBase ())
+                               return false;
+
+                       //
+                       // Now define the accessors
+                       //
+
+                       AddBuilder = Add.Define (Parent, ip);
+                       if (AddBuilder == null)
+                               return false;
+
+                       RemoveBuilder = Remove.Define (Parent, ip);
+                       if (RemoveBuilder == null)
+                               return false;
+
+                       EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, e_attr, MemberType);
+                                       
+                       if (Add.Block == null && Remove.Block == null && !IsInterface) {
+                                       FieldBuilder = Parent.TypeBuilder.DefineField (
+                                               Name, MemberType,
+                                               FieldAttributes.Private | ((ModFlags & Modifiers.STATIC) != 0 ? FieldAttributes.Static : 0));
+                                       TypeManager.RegisterPrivateFieldOfEvent (
+                                               (EventInfo) EventBuilder, FieldBuilder);
+                                       TypeManager.RegisterFieldBase (FieldBuilder, this);
+                               }
+                       
+                               EventBuilder.SetAddOnMethod (AddBuilder);
+                               EventBuilder.SetRemoveOnMethod (RemoveBuilder);
+
+                               TypeManager.RegisterEvent (EventBuilder, AddBuilder, RemoveBuilder);
+                       return true;
+               }
+
+               protected override bool CheckBase ()
+               {
+                       if (!base.CheckBase ())
+                               return false;
+                       if (conflict_symbol != null && (ModFlags & Modifiers.NEW) == 0) {
+                               if (!(conflict_symbol is EventInfo)) {
+                                       Report.SymbolRelatedToPreviousError (conflict_symbol);
+                                       Report.Error (72, Location, "Event '{0}' can override only event", GetSignatureForError (Parent));
+                                       return false;
+                               }
+                       }
+                       return true;
+               }
+
+               public override void Emit ()
+               {
+                       if (OptAttributes != null) {
+                               EmitContext ec = new EmitContext (
+                                       Parent, Location, null, MemberType, ModFlags);
+                               OptAttributes.Emit (ec, this);
+                       }
+
+                       if (!IsInterface) {
+                               Add.Emit (Parent);
+                               Remove.Emit (Parent);
+                       }
+
+                       base.Emit ();
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       if (EventBuilder == null)
+                               return base.GetSignatureForError (Parent);
+
+                       return TypeManager.GetFullNameSignature (EventBuilder);
+               }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "E:"; }
+               }
+       }
+
+       public class Indexer : PropertyBase {
+
+               class GetIndexerMethod: GetMethod
+               {
+                       public GetIndexerMethod (MethodCore method):
+                               base (method)
+                       {
+                       }
+
+                       public GetIndexerMethod (MethodCore method, Accessor accessor):
+                               base (method, accessor)
+                       {
+                       }
+
+                       public override Type[] ParameterTypes {
+                               get {
+                                       return method.ParameterTypes;
+                               }
+                       }
+               }
+
+               class SetIndexerMethod: SetMethod
+               {
+                       readonly Parameters parameters;
+
+                       public SetIndexerMethod (MethodCore method):
+                               base (method)
+                       {
+                       }
+
+                       public SetIndexerMethod (MethodCore method, Parameters parameters, Accessor accessor):
+                               base (method, accessor)
+                       {
+                               this.parameters = parameters;
+                       }
+
+                       public override Type[] ParameterTypes {
+                               get {
+                                       int top = method.ParameterTypes.Length;
+                                       Type [] set_pars = new Type [top + 1];
+                                       method.ParameterTypes.CopyTo (set_pars, 0);
+                                       set_pars [top] = method.MemberType;
+                                       return set_pars;
+                               }
+                       }
+
+                       protected override InternalParameters GetParameterInfo (EmitContext ec)
+                       {
+                               Parameter [] fixed_parms = parameters.FixedParameters;
+
+                               if (fixed_parms == null){
+                                       throw new Exception ("We currently do not support only array arguments in an indexer at: " + method.Location);
+                                       // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
+                                       // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
+                                       //
+                                       // Here is the problem: the `value' parameter has
+                                       // to come *after* the array parameter in the declaration
+                                       // like this:
+                                       // X (object [] x, Type value)
+                                       // .param [0]
+                                       //
+                                       // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
+                                       // BUG BUG BUG BUG BUG BUG BUG BUG BUG BUG
+                                       
+                               }
+                               
+                               Parameter [] tmp = new Parameter [fixed_parms.Length + 1];
+
+                               fixed_parms.CopyTo (tmp, 0);
+                               tmp [fixed_parms.Length] = new Parameter (
+                                       method.Type, "value", Parameter.Modifier.NONE, null);
+
+                               Parameters set_formal_params = new Parameters (tmp, null, method.Location);
+                               Type [] types = set_formal_params.GetParameterInfo (ec);
+                               
+                               return new InternalParameters (types, set_formal_params);
+                       }
+               }
+
+               const int AllowedModifiers =
+                       Modifiers.NEW |
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE |
+                       Modifiers.VIRTUAL |
+                       Modifiers.SEALED |
+                       Modifiers.OVERRIDE |
+                       Modifiers.UNSAFE |
+                       Modifiers.EXTERN |
+                       Modifiers.ABSTRACT;
+
+               const int AllowedInterfaceModifiers =
+                       Modifiers.NEW;
+
+               //
+               // Are we implementing an interface ?
+               //
+               public Indexer (TypeContainer parent, Expression type, MemberName name, int mod,
+                               bool is_iface, Parameters parameters, Attributes attrs,
+                               Accessor get_block, Accessor set_block, Location loc)
+                       : base (parent, type, mod,
+                               is_iface ? AllowedInterfaceModifiers : AllowedModifiers,
+                               is_iface, name, parameters, attrs, loc)
+               {
+                       if (get_block == null)
+                               Get = new GetIndexerMethod (this);
+                       else
+                               Get = new GetIndexerMethod (this, get_block);
+
+                       if (set_block == null)
+                               Set = new SetIndexerMethod (this);
+                       else
+                               Set = new SetIndexerMethod (this, parameters, set_block);
+               }
+
+               public override bool Define ()
+               {
+                       PropertyAttributes prop_attr =
+                               PropertyAttributes.RTSpecialName |
+                               PropertyAttributes.SpecialName;
+                       
+                       if (!DoDefineBase ())
+                               return false;
+
+                       if (!base.Define ())
+                               return false;
+
+                       if (OptAttributes != null) {
+                               Attribute indexer_attr = OptAttributes.Search (TypeManager.indexer_name_type, ec);
+                               if (indexer_attr != null) {
+                                       // Remove the attribute from the list because it is not emitted
+                                       OptAttributes.Attrs.Remove (indexer_attr);
+
+                                       ShortName = indexer_attr.GetIndexerAttributeValue (ec);
+
+                                       if (IsExplicitImpl) {
+                                               Report.Error (415, indexer_attr.Location,
+                                                             "The 'IndexerName' attribute is valid only on an" +
+                                                             "indexer that is not an explicit interface member declaration");
+                                               return false;
+                                       }
+                               
+                                       if ((ModFlags & Modifiers.OVERRIDE) != 0) {
+                                               Report.Error (609, indexer_attr.Location,
+                                                             "Cannot set the 'IndexerName' attribute on an indexer marked override");
+                                               return false;
+                                       }
+
+//                                     if (!Tokenizer.IsValidIdentifier (ShortName)) {
+//                                             Report.Error (633, indexer_attr.Location,
+//                                                           "The argument to the 'IndexerName' attribute must be a valid identifier");
+//                                             return false;
+//                                     }
+
+                                       UpdateMemberName ();
+                               }
+                       }
+
+                       if (InterfaceType != null) {
+                               string parent_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
+                               if (parent_IndexerName != Name)
+                                       ShortName = parent_IndexerName;
+                               UpdateMemberName ();
+                       }
+
+                       if (!Parent.AddToMemberContainer (this, true) ||
+                           !Parent.AddToMemberContainer (Get, true) || !Parent.AddToMemberContainer (Set, true))
+                               return false;
+
+                       if (!CheckBase ())
+                               return false;
+
+                       flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
+                       if (!Get.IsDummy){
+                               GetBuilder = Get.Define (Parent);
+                               if (GetBuilder == null)
+                                       return false;
+                       }
+                       
+                       if (!Set.IsDummy){
+                               SetBuilder = Set.Define (Parent);
+                               if (SetBuilder == null)
+                                       return false;
+                       }
+
+                       //
+                       // Now name the parameters
+                       //
+                       Parameter [] p = Parameters.FixedParameters;
+                       if (p != null) {
+                               if ((p [0].ModFlags & Parameter.Modifier.ISBYREF) != 0) {
+                                       Report.Error (631, Location, "ref and out are not valid in this context");
+                                       return false;
+                               }
+
+                               int i;
+                               
+                               for (i = 0; i < p.Length; ++i) {
+                                       if (!Get.IsDummy)
+                                               GetBuilder.DefineParameter (
+                                                       i + 1, p [i].Attributes, p [i].Name);
+
+                                       if (!Set.IsDummy)
+                                               SetBuilder.DefineParameter (
+                                                       i + 1, p [i].Attributes, p [i].Name);
+                               }
+
+                               if (!Set.IsDummy)
+                                       SetBuilder.DefineParameter (
+                                               i + 1, ParameterAttributes.None, "value");
+                                       
+                               if (i != ParameterTypes.Length) {
+                                       Parameter array_param = Parameters.ArrayParameter;
+
+                                       SetBuilder.DefineParameter (
+                                               i + 1, array_param.Attributes, array_param.Name);
+                               }
+                       }
+
+                               PropertyBuilder = Parent.TypeBuilder.DefineProperty (
+                               Name, prop_attr, MemberType, ParameterTypes);
+
+                               if (!Get.IsDummy)
+                                       PropertyBuilder.SetGetMethod (GetBuilder);
+
+                               if (!Set.IsDummy)
+                                       PropertyBuilder.SetSetMethod (SetBuilder);
+                               
+                       TypeManager.RegisterIndexer (PropertyBuilder, GetBuilder, SetBuilder, ParameterTypes);
+
+                       return true;
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       if (PropertyBuilder == null)
+                               return GetSignatureForError (Parent);
+
+                       return TypeManager.CSharpSignature (PropertyBuilder, true);
+               }
+
+               public override string GetSignatureForError(TypeContainer tc)
+               {
+                       return String.Concat (tc.Name, ".this[", Parameters.FixedParameters [0].TypeName.ToString (), ']');
+               }
+       }
+
+       public class Operator : MethodCore, IIteratorContainer {
+
+               const int AllowedModifiers =
+                       Modifiers.PUBLIC |
+                       Modifiers.UNSAFE |
+                       Modifiers.EXTERN |
+                       Modifiers.STATIC;
+
+               public enum OpType : byte {
+
+                       // Unary operators
+                       LogicalNot,
+                       OnesComplement,
+                       Increment,
+                       Decrement,
+                       True,
+                       False,
+
+                       // Unary and Binary operators
+                       Addition,
+                       Subtraction,
+
+                       UnaryPlus,
+                       UnaryNegation,
+                       
+                       // Binary operators
+                       Multiply,
+                       Division,
+                       Modulus,
+                       BitwiseAnd,
+                       BitwiseOr,
+                       ExclusiveOr,
+                       LeftShift,
+                       RightShift,
+                       Equality,
+                       Inequality,
+                       GreaterThan,
+                       LessThan,
+                       GreaterThanOrEqual,
+                       LessThanOrEqual,
+
+                       // Implicit and Explicit
+                       Implicit,
+                       Explicit
+               };
+
+               public readonly OpType OperatorType;
+               public MethodBuilder   OperatorMethodBuilder;
+               
+               public Method OperatorMethod;
+
+               static string[] attribute_targets = new string [] { "method", "return" };
+
+               public Operator (TypeContainer parent, OpType type, Expression ret_type,
+                                int mod_flags, Parameters parameters,
+                                ToplevelBlock block, Attributes attrs, Location loc)
+                       : base (parent, null, ret_type, mod_flags, AllowedModifiers, false,
+                               new MemberName ("op_" + type), attrs, parameters, loc)
+               {
+                       OperatorType = type;
+                       Block = block;
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb) 
+               {
+                       OperatorMethod.ApplyAttributeBuilder (a, cb);
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Method; 
+                       }
+               }
+               
+               protected override bool CheckGenericOverride (MethodInfo method,  string name)
+               {
+                       return true;
+               }
+
+               protected override bool CheckForDuplications()
+               {
+                       ArrayList ar = Parent.Operators;
+                       if (ar != null) {
+                               int arLen = ar.Count;
+
+                               for (int i = 0; i < arLen; i++) {
+                                       Operator o = (Operator) ar [i];
+                                       if (IsDuplicateImplementation (o))
+                                               return false;
+                               }
+                       }
+
+                       ar = Parent.Methods;
+                       if (ar != null) {
+                               int arLen = ar.Count;
+
+                               for (int i = 0; i < arLen; i++) {
+                                       Method m = (Method) ar [i];
+                                       if (IsDuplicateImplementation (m))
+                                               return false;
+                               }
+                       }
+
+                       return true;
+               }
+
+               public override bool Define ()
+               {
+                       const int RequiredModifiers = Modifiers.PUBLIC | Modifiers.STATIC;
+                       if ((ModFlags & RequiredModifiers) != RequiredModifiers){
+                               Report.Error (558, Location, "User defined operators '{0}' must be declared static and public", GetSignatureForError (Parent));
+                               return false;
+                       }
+
+                       if (!DoDefine (ds))
+                               return false;
+
+                       OperatorMethod = new Method (
+                               Parent, null, Type, ModFlags, false, MemberName,
+                               Parameters, OptAttributes, Location);
+
+                       OperatorMethod.Block = Block;
+                       OperatorMethod.IsOperator = true;                       
+                       OperatorMethod.flags |= MethodAttributes.SpecialName | MethodAttributes.HideBySig;
+                       OperatorMethod.Define ();
+
+                       if (OperatorMethod.MethodBuilder == null)
+                               return false;
+                       
+                       OperatorMethodBuilder = OperatorMethod.MethodBuilder;
+
+                       parameter_types = OperatorMethod.ParameterTypes;
+                       Type declaring_type = OperatorMethod.MethodData.DeclaringType;
+                       Type return_type = OperatorMethod.ReturnType;
+                       Type first_arg_type = parameter_types [0];
+
+                       if (!CheckBase ())
+                               return false;
+
+                       // Rules for conversion operators
+                       
+                       if (OperatorType == OpType.Implicit || OperatorType == OpType.Explicit) {
+                               if (first_arg_type == return_type && first_arg_type == declaring_type){
+                                       Report.Error (
+                                               555, Location,
+                                               "User-defined conversion cannot take an object of the " +
+                                               "enclosing type and convert to an object of the enclosing" +
+                                               " type");
+                                       return false;
+                               }
+                               
+                               if (first_arg_type != declaring_type && return_type != declaring_type){
+                                       Report.Error (
+                                               556, Location, 
+                                               "User-defined conversion must convert to or from the " +
+                                               "enclosing type");
+                                       return false;
+                               }
+                               
+                               if (first_arg_type == TypeManager.object_type ||
+                                   return_type == TypeManager.object_type){
+                                       Report.Error (
+                                               -8, Location,
+                                               "User-defined conversion cannot convert to or from " +
+                                               "object type");
+                                       return false;
+                               }
+
+                               if (first_arg_type.IsInterface || return_type.IsInterface){
+                                       Report.Error (
+                                               552, Location,
+                                               "User-defined conversion cannot convert to or from an " +
+                                               "interface type");
+                                       return false;
+                               }
+                               
+                               if (first_arg_type.IsSubclassOf (return_type)
+                                       || return_type.IsSubclassOf (first_arg_type)){
+                                       if (declaring_type.IsSubclassOf (return_type)) {
+                                               Report.Error (553, Location, "'{0}' : user defined conversion to/from base class", GetSignatureForError ());
+                                               return false;
+                                       }
+                                       Report.Error (554, Location, "'{0}' : user defined conversion to/from derived class", GetSignatureForError ());
+                                       return false;
+                               }
+                       } else if (OperatorType == OpType.LeftShift || OperatorType == OpType.RightShift) {
+                               if (first_arg_type != declaring_type || parameter_types [1] != TypeManager.int32_type) {
+                                       Report.Error (564, Location, "Overloaded shift operator must have the type of the first operand be the containing type, and the type of the second operand must be int");
+                                       return false;
+                               }
+                       } else if (Parameters.FixedParameters.Length == 1) {
+                               // Checks for Unary operators
+                               
+                               if (OperatorType == OpType.Increment || OperatorType == OpType.Decrement) {
+                                       if (return_type != declaring_type && !return_type.IsSubclassOf (declaring_type)) {
+                                               Report.Error (448, Location,
+                                                       "The return type for ++ or -- operator must be the containing type or derived from the containing type");
+                                               return false;
+                                       }
+                               if (first_arg_type != declaring_type){
+                                       Report.Error (
+                                                       559, Location, "The parameter type for ++ or -- operator must be the containing type");
+                                       return false;
+                               }
+                               }
+                               
+                               if (first_arg_type != declaring_type){
+                                               Report.Error (
+                                               562, Location,
+                                               "The parameter of a unary operator must be the " +
+                                               "containing type");
+                                               return false;
+                               }
+                               
+                               if (OperatorType == OpType.True || OperatorType == OpType.False) {
+                                       if (return_type != TypeManager.bool_type){
+                                               Report.Error (
+                                                       215, Location,
+                                                       "The return type of operator True or False " +
+                                                       "must be bool");
+                                               return false;
+                                       }
+                               }
+                               
+                       } else {
+                               // Checks for Binary operators
+                               
+                               if (first_arg_type != declaring_type &&
+                                   parameter_types [1] != declaring_type){
+                                       Report.Error (
+                                               563, Location,
+                                               "One of the parameters of a binary operator must " +
+                                               "be the containing type");
+                                       return false;
+                               }
+                       }
+
+                       return true;
+               }
+               
+               public override void Emit ()
+               {
+                       //
+                       // abstract or extern methods have no bodies
+                       //
+                       if ((ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) != 0)
+                               return;
+                       
+                       OperatorMethod.Emit ();
+                       Block = null;
+               }
+
+               // Operator cannot be override
+               protected override MethodInfo FindOutParentMethod (TypeContainer container, ref Type parent_ret_type)
+               {
+                       return null;
+               }
+
+               public static string GetName (OpType ot)
+               {
+                       switch (ot){
+                       case OpType.LogicalNot:
+                               return "!";
+                       case OpType.OnesComplement:
+                               return "~";
+                       case OpType.Increment:
+                               return "++";
+                       case OpType.Decrement:
+                               return "--";
+                       case OpType.True:
+                               return "true";
+                       case OpType.False:
+                               return "false";
+                       case OpType.Addition:
+                               return "+";
+                       case OpType.Subtraction:
+                               return "-";
+                       case OpType.UnaryPlus:
+                               return "+";
+                       case OpType.UnaryNegation:
+                               return "-";
+                       case OpType.Multiply:
+                               return "*";
+                       case OpType.Division:
+                               return "/";
+                       case OpType.Modulus:
+                               return "%";
+                       case OpType.BitwiseAnd:
+                               return "&";
+                       case OpType.BitwiseOr:
+                               return "|";
+                       case OpType.ExclusiveOr:
+                               return "^";
+                       case OpType.LeftShift:
+                               return "<<";
+                       case OpType.RightShift:
+                               return ">>";
+                       case OpType.Equality:
+                               return "==";
+                       case OpType.Inequality:
+                               return "!=";
+                       case OpType.GreaterThan:
+                               return ">";
+                       case OpType.LessThan:
+                               return "<";
+                       case OpType.GreaterThanOrEqual:
+                               return ">=";
+                       case OpType.LessThanOrEqual:
+                               return "<=";
+                       case OpType.Implicit:
+                               return "implicit";
+                       case OpType.Explicit:
+                               return "explicit";
+                       default: return "";
+                       }
+               }
+
+               public override string GetSignatureForError (TypeContainer tc)
+               {
+                       StringBuilder sb = new StringBuilder ();
+                       sb.AppendFormat ("{0}.operator {1} {2}({3}", tc.Name, GetName (OperatorType), Type.Type == null ? Type.ToString () : TypeManager.CSharpName (Type.Type),
+                               Parameters.FixedParameters [0].GetSignatureForError ());
+                       
+                       if (Parameters.FixedParameters.Length > 1) {
+                               sb.Append (",");
+                               sb.Append (Parameters.FixedParameters [1].GetSignatureForError ());
+                       }
+                       sb.Append (")");
+                       return sb.ToString ();
+               }
+
+               public override string GetSignatureForError ()
+               {
+                       return ToString ();
+               }
+               
+               public override string ToString ()
+               {
+                       if (OperatorMethod == null)
+                               return Name;
+
+                       Type return_type = OperatorMethod.ReturnType;
+                       Type [] param_types = OperatorMethod.ParameterTypes;
+                       
+                       if (Parameters.FixedParameters.Length == 1)
+                               return String.Format (
+                                       "{0} operator {1}({2})",
+                                       TypeManager.CSharpName (return_type),
+                                       GetName (OperatorType),
+                                       param_types [0]);
+                       else
+                               return String.Format (
+                                       "{0} operator {1}({2}, {3})",
+                                       TypeManager.CSharpName (return_type),
+                                       GetName (OperatorType),
+                                       param_types [0], param_types [1]);
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+
+               public void SetYields ()
+               {
+                       ModFlags |= Modifiers.METHOD_YIELDS;
+               }
+       }
+
+       //
+       // This is used to compare method signatures
+       //
+       struct MethodSignature {
+               public string Name;
+               public Type RetType;
+               public Type [] Parameters;
+               
+               /// <summary>
+               ///    This delegate is used to extract methods which have the
+               ///    same signature as the argument
+               /// </summary>
+               public static MemberFilter method_signature_filter = new MemberFilter (MemberSignatureCompare);
+               
+               public MethodSignature (string name, Type ret_type, Type [] parameters)
+               {
+                       Name = name;
+                       RetType = ret_type;
+
+                       if (parameters == null)
+                               Parameters = TypeManager.NoTypes;
+                       else
+                               Parameters = parameters;
+               }
+
+               public override string ToString ()
+               {
+                       string pars = "";
+                       if (Parameters.Length != 0){
+                               System.Text.StringBuilder sb = new System.Text.StringBuilder ();
+                               for (int i = 0; i < Parameters.Length; i++){
+                                       sb.Append (Parameters [i]);
+                                       if (i+1 < Parameters.Length)
+                                               sb.Append (", ");
+                               }
+                               pars = sb.ToString ();
+                       }
+
+                       return String.Format ("{0} {1} ({2})", RetType, Name, pars);
+               }
+               
+               public override int GetHashCode ()
+               {
+                       return Name.GetHashCode ();
+               }
+
+               public override bool Equals (Object o)
+               {
+                       MethodSignature other = (MethodSignature) o;
+
+                       if (other.Name != Name)
+                               return false;
+
+                       if (other.RetType != RetType)
+                               return false;
+                       
+                       if (Parameters == null){
+                               if (other.Parameters == null)
+                                       return true;
+                               return false;
+                       }
+
+                       if (other.Parameters == null)
+                               return false;
+                       
+                       int c = Parameters.Length;
+                       if (other.Parameters.Length != c)
+                               return false;
+
+                       for (int i = 0; i < c; i++)
+                               if (other.Parameters [i] != Parameters [i])
+                                       return false;
+
+                       return true;
+               }
+
+               static bool MemberSignatureCompare (MemberInfo m, object filter_criteria)
+               {
+                       MethodSignature sig = (MethodSignature) filter_criteria;
+
+                       if (m.Name != sig.Name)
+                               return false;
+
+                       Type ReturnType;
+                       MethodInfo mi = m as MethodInfo;
+                       PropertyInfo pi = m as PropertyInfo;
+
+                       if (mi != null)
+                               ReturnType = mi.ReturnType;
+                       else if (pi != null)
+                               ReturnType = pi.PropertyType;
+                       else
+                               return false;
+                       
+                       //
+                       // we use sig.RetType == null to mean `do not check the
+                       // method return value.  
+                       //
+                       if (sig.RetType != null)
+                               if (ReturnType != sig.RetType)
+                                       return false;
+
+                       Type [] args;
+                       if (mi != null)
+                               args = TypeManager.GetArgumentTypes (mi);
+                       else
+                               args = TypeManager.GetArgumentTypes (pi);
+                       Type [] sigp = sig.Parameters;
+
+                       if (args.Length != sigp.Length)
+                               return false;
+
+                       for (int i = args.Length; i > 0; ){
+                               i--;
+                               if (args [i] != sigp [i])
+                                       return false;
+                       }
+                       return true;
+               }
+       }
+}
diff --git a/mcs/bmcs/codegen.cs b/mcs/bmcs/codegen.cs
new file mode 100644 (file)
index 0000000..cd0d122
--- /dev/null
@@ -0,0 +1,1367 @@
+//
+// codegen.cs: The code generator
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001, 2002, 2003 Ximian, Inc.
+// (C) 2004 Novell, Inc.
+//
+//#define PRODUCTION
+using System;
+using System.IO;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Security.Cryptography;
+using System.Security.Permissions;
+
+using Mono.Security.Cryptography;
+
+namespace Mono.CSharp {
+
+       /// <summary>
+       ///    Code generator class.
+       /// </summary>
+       public class CodeGen {
+               static AppDomain current_domain;
+               static public SymbolWriter SymbolWriter;
+
+               public static AssemblyClass Assembly;
+               public static ModuleClass Module;
+
+               static CodeGen ()
+               {
+                       Assembly = new AssemblyClass ();
+                       Module = new ModuleClass (RootContext.Unsafe);
+               }
+
+               public static string Basename (string name)
+               {
+                       int pos = name.LastIndexOf ('/');
+
+                       if (pos != -1)
+                               return name.Substring (pos + 1);
+
+                       pos = name.LastIndexOf ('\\');
+                       if (pos != -1)
+                               return name.Substring (pos + 1);
+
+                       return name;
+               }
+
+               public static string Dirname (string name)
+               {
+                       int pos = name.LastIndexOf ('/');
+
+                       if (pos != -1)
+                               return name.Substring (0, pos);
+
+                       pos = name.LastIndexOf ('\\');
+                       if (pos != -1)
+                               return name.Substring (0, pos);
+
+                       return ".";
+               }
+
+               static string TrimExt (string name)
+               {
+                       int pos = name.LastIndexOf ('.');
+
+                       return name.Substring (0, pos);
+               }
+
+               static public string FileName;
+
+               //
+               // Initializes the symbol writer
+               //
+               static void InitializeSymbolWriter (string filename)
+               {
+                       SymbolWriter = SymbolWriter.GetSymbolWriter (Module.Builder, filename);
+
+                       //
+                       // If we got an ISymbolWriter instance, initialize it.
+                       //
+                       if (SymbolWriter == null) {
+                               Report.Warning (
+                                       -18, "Could not find the symbol writer assembly (Mono.CompilerServices.SymbolWriter.dll). This is normally an installation problem. Please make sure to compile and install the mcs/class/Mono.CompilerServices.SymbolWriter directory.");
+                               return;
+                       }
+               }
+
+               //
+               // Initializes the code generator variables
+               //
+               static public void Init (string name, string output, bool want_debugging_support)
+               {
+                       FileName = output;
+                       AssemblyName an = Assembly.GetAssemblyName (name, output);
+
+                       if (an.KeyPair != null) {
+                               // If we are going to strong name our assembly make
+                               // sure all its refs are strong named
+                               foreach (Assembly a in TypeManager.GetAssemblies ()) {
+                                       AssemblyName ref_name = a.GetName ();
+                                       byte [] b = ref_name.GetPublicKeyToken ();
+                                       if (b == null || b.Length == 0) {
+                                               Report.Warning (1577, "Assembly generation failed " +
+                                                               "-- Referenced assembly '" +
+                                                               ref_name.Name +
+                                                               "' does not have a strong name.");
+                                               //Environment.Exit (1);
+                                       }
+                               }
+                       }
+                       
+                       current_domain = AppDomain.CurrentDomain;
+
+                       try {
+                               Assembly.Builder = current_domain.DefineDynamicAssembly (an,
+                                       AssemblyBuilderAccess.Save, Dirname (name));
+                       }
+                       catch (ArgumentException) {
+                               // specified key may not be exportable outside it's container
+                               if (RootContext.StrongNameKeyContainer != null) {
+                                       Report.Error (1548, "Could not access the key inside the container `" +
+                                               RootContext.StrongNameKeyContainer + "'.");
+                                       Environment.Exit (1);
+                               }
+                               throw;
+                       }
+                       catch (CryptographicException) {
+                               if ((RootContext.StrongNameKeyContainer != null) || (RootContext.StrongNameKeyFile != null)) {
+                                       Report.Error (1548, "Could not use the specified key to strongname the assembly.");
+                                       Environment.Exit (1);
+                               }
+                               throw;
+                       }
+
+                       //
+                       // Pass a path-less name to DefineDynamicModule.  Wonder how
+                       // this copes with output in different directories then.
+                       // FIXME: figure out how this copes with --output /tmp/blah
+                       //
+                       // If the third argument is true, the ModuleBuilder will dynamically
+                       // load the default symbol writer.
+                       //
+                       Module.Builder = Assembly.Builder.DefineDynamicModule (
+                               Basename (name), Basename (output), false);
+
+                       if (want_debugging_support)
+                               InitializeSymbolWriter (output);
+               }
+
+               static public void Save (string name)
+               {
+                       try {
+                               Assembly.Builder.Save (Basename (name));
+                       }
+                       catch (COMException) {
+                               if ((RootContext.StrongNameKeyFile == null) || (!RootContext.StrongNameDelaySign))
+                                       throw;
+
+                               // FIXME: it seems Microsoft AssemblyBuilder doesn't like to delay sign assemblies 
+                               Report.Error (1548, "Couldn't delay-sign the assembly with the '" +
+                                       RootContext.StrongNameKeyFile +
+                                       "', Use MCS with the Mono runtime or CSC to compile this assembly.");
+                       }
+                       catch (System.IO.IOException io) {
+                               Report.Error (16, "Could not write to file `"+name+"', cause: " + io.Message);
+                       }
+
+                       if (SymbolWriter != null)
+                               SymbolWriter.WriteSymbolFile ();
+               }
+
+               public static void AddGlobalAttributes (ArrayList attrs)
+               {
+                       foreach (Attribute attr in attrs) {
+                               if (attr.IsAssemblyAttribute)
+                                       Assembly.AddAttribute (attr);
+                               else if (attr.IsModuleAttribute)
+                                       Module.AddAttribute (attr);
+                       }
+               }
+       }
+
+       //
+       // Provides "local" store across code that can yield: locals
+       // or fields, notice that this should not be used by anonymous
+       // methods to create local storage, those only require
+       // variable mapping.
+       //
+       public class VariableStorage {
+               FieldBuilder fb;
+               LocalBuilder local;
+               
+               static int count;
+               
+               public VariableStorage (EmitContext ec, Type t)
+               {
+                       count++;
+                       if (ec.InIterator)
+                               fb = ec.CurrentIterator.MapVariable ("s_", count.ToString (), t);
+                       else
+                               local = ec.ig.DeclareLocal (t);
+               }
+
+               public void EmitThis (ILGenerator ig)
+               {
+                       if (fb != null)
+                               ig.Emit (OpCodes.Ldarg_0);
+               }
+
+               public void EmitStore (ILGenerator ig)
+               {
+                       if (fb == null)
+                               ig.Emit (OpCodes.Stloc, local);
+                       else
+                               ig.Emit (OpCodes.Stfld, fb);
+               }
+
+               public void EmitLoad (ILGenerator ig)
+               {
+                       if (fb == null)
+                               ig.Emit (OpCodes.Ldloc, local);
+                       else 
+                               ig.Emit (OpCodes.Ldfld, fb);
+               }
+
+               public void EmitLoadAddress (ILGenerator ig)
+               {
+                       if (fb == null)
+                               ig.Emit (OpCodes.Ldloca, local);
+                       else 
+                               ig.Emit (OpCodes.Ldflda, fb);
+               }
+               
+               public void EmitCall (ILGenerator ig, MethodInfo mi)
+               {
+                       // FIXME : we should handle a call like tostring
+                       // here, where boxing is needed. However, we will
+                       // never encounter that with the current usage.
+                       
+                       bool value_type_call;
+                       EmitThis (ig);
+                       if (fb == null) {
+                               value_type_call = local.LocalType.IsValueType;
+                               
+                               if (value_type_call)
+                                       ig.Emit (OpCodes.Ldloca, local);
+                               else
+                                       ig.Emit (OpCodes.Ldloc, local);
+                       } else {
+                               value_type_call = fb.FieldType.IsValueType;
+                               
+                               if (value_type_call)
+                                       ig.Emit (OpCodes.Ldflda, fb);
+                               else
+                                       ig.Emit (OpCodes.Ldfld, fb);
+                       }
+                       
+                       ig.Emit (value_type_call ? OpCodes.Call : OpCodes.Callvirt, mi);
+               }
+       }
+       
+       /// <summary>
+       ///   An Emit Context is created for each body of code (from methods,
+       ///   properties bodies, indexer bodies or constructor bodies)
+       /// </summary>
+       public class EmitContext {
+               public DeclSpace DeclSpace;
+               public DeclSpace TypeContainer;
+               public ILGenerator   ig;
+
+               /// <summary>
+               ///   This variable tracks the `checked' state of the compilation,
+               ///   it controls whether we should generate code that does overflow
+               ///   checking, or if we generate code that ignores overflows.
+               ///
+               ///   The default setting comes from the command line option to generate
+               ///   checked or unchecked code plus any source code changes using the
+               ///   checked/unchecked statements or expressions.   Contrast this with
+               ///   the ConstantCheckState flag.
+               /// </summary>
+               
+               public bool CheckState;
+
+               /// <summary>
+               ///   The constant check state is always set to `true' and cant be changed
+               ///   from the command line.  The source code can change this setting with
+               ///   the `checked' and `unchecked' statements and expressions. 
+               /// </summary>
+               public bool ConstantCheckState;
+
+               /// <summary>
+               ///   Whether we are emitting code inside a static or instance method
+               /// </summary>
+               public bool IsStatic;
+
+               /// <summary>
+               ///   Whether we are emitting a field initializer
+               /// </summary>
+               public bool IsFieldInitializer;
+
+               /// <summary>
+               ///   The value that is allowed to be returned or NULL if there is no
+               ///   return type.
+               /// </summary>
+               public Type ReturnType;
+
+               /// <summary>
+               ///   Points to the Type (extracted from the TypeContainer) that
+               ///   declares this body of code
+               /// </summary>
+               public Type ContainerType;
+               
+               /// <summary>
+               ///   Whether this is generating code for a constructor
+               /// </summary>
+               public bool IsConstructor;
+
+               /// <summary>
+               ///   Whether we're control flow analysis enabled
+               /// </summary>
+               public bool DoFlowAnalysis;
+               
+               /// <summary>
+               ///   Keeps track of the Type to LocalBuilder temporary storage created
+               ///   to store structures (used to compute the address of the structure
+               ///   value on structure method invocations)
+               /// </summary>
+               public Hashtable temporary_storage;
+
+               public Block CurrentBlock;
+
+               public int CurrentFile;
+
+               /// <summary>
+               ///   The location where we store the return value.
+               /// </summary>
+               LocalBuilder return_value;
+
+               /// <summary>
+               ///   The location where return has to jump to return the
+               ///   value
+               /// </summary>
+               public Label ReturnLabel;
+
+               /// <summary>
+               ///   If we already defined the ReturnLabel
+               /// </summary>
+               public bool HasReturnLabel;
+
+               /// <summary>
+               ///   Whether we are inside an iterator block.
+               /// </summary>
+               public bool InIterator;
+
+               public bool IsLastStatement;
+               
+               /// <summary>
+               ///   Whether remapping of locals, parameters and fields is turned on.
+               ///   Used by iterators and anonymous methods.
+               /// </summary>
+               public bool RemapToProxy;
+
+               /// <summary>
+               ///  Whether we are inside an unsafe block
+               /// </summary>
+               public bool InUnsafe;
+
+               /// <summary>
+               ///  Whether we are in a `fixed' initialization
+               /// </summary>
+               public bool InFixedInitializer;
+
+               /// <summary>
+               ///  Whether we are inside an anonymous method.
+               /// </summary>
+               public AnonymousMethod CurrentAnonymousMethod;
+               
+               /// <summary>
+               ///   Location for this EmitContext
+               /// </summary>
+               public Location loc;
+
+               /// <summary>
+               ///   Used to flag that it is ok to define types recursively, as the
+               ///   expressions are being evaluated as part of the type lookup
+               ///   during the type resolution process
+               /// </summary>
+               public bool ResolvingTypeTree;
+               
+               /// <summary>
+               ///   Inside an enum definition, we do not resolve enumeration values
+               ///   to their enumerations, but rather to the underlying type/value
+               ///   This is so EnumVal + EnumValB can be evaluated.
+               ///
+               ///   There is no "E operator + (E x, E y)", so during an enum evaluation
+               ///   we relax the rules
+               /// </summary>
+               public bool InEnumContext;
+
+               /// <summary>
+               ///   Anonymous methods can capture local variables and fields,
+               ///   this object tracks it.  It is copied from the TopLevelBlock
+               ///   field.
+               /// </summary>
+               public CaptureContext capture_context;
+
+               /// <summary>
+               /// Trace when method is called and is obsolete then this member suppress message
+               /// when call is inside next [Obsolete] method or type.
+               /// </summary>
+               public bool TestObsoleteMethodUsage = true;
+
+               /// <summary>
+               ///    The current iterator
+               /// </summary>
+               public Iterator CurrentIterator;
+
+               /// <summary>
+               ///    Whether we are in the resolving stage or not
+               /// </summary>
+               enum Phase {
+                       Created,
+                       Resolving,
+                       Emitting
+               }
+               
+               Phase current_phase;
+               
+               FlowBranching current_flow_branching;
+               
+               public EmitContext (DeclSpace parent, DeclSpace ds, Location l, ILGenerator ig,
+                                   Type return_type, int code_flags, bool is_constructor)
+               {
+                       this.ig = ig;
+
+                       TypeContainer = parent;
+                       DeclSpace = ds;
+                       CheckState = RootContext.Checked;
+                       ConstantCheckState = true;
+                       
+                       IsStatic = (code_flags & Modifiers.STATIC) != 0;
+                       InIterator = (code_flags & Modifiers.METHOD_YIELDS) != 0;
+                       RemapToProxy = InIterator;
+                       ReturnType = return_type;
+                       IsConstructor = is_constructor;
+                       CurrentBlock = null;
+                       CurrentFile = 0;
+                       current_phase = Phase.Created;
+                       
+                       if (parent != null){
+                               // Can only be null for the ResolveType contexts.
+                               ContainerType = parent.TypeBuilder;
+                               if (parent.UnsafeContext)
+                                       InUnsafe = true;
+                               else
+                                       InUnsafe = (code_flags & Modifiers.UNSAFE) != 0;
+                       }
+                       loc = l;
+
+                       if (ReturnType == TypeManager.void_type)
+                               ReturnType = null;
+               }
+
+               public EmitContext (TypeContainer tc, Location l, ILGenerator ig,
+                                   Type return_type, int code_flags, bool is_constructor)
+                       : this (tc, tc, l, ig, return_type, code_flags, is_constructor)
+               {
+               }
+
+               public EmitContext (TypeContainer tc, Location l, ILGenerator ig,
+                                   Type return_type, int code_flags)
+                       : this (tc, tc, l, ig, return_type, code_flags, false)
+               {
+               }
+
+               public FlowBranching CurrentBranching {
+                       get {
+                               return current_flow_branching;
+                       }
+               }
+
+               public bool HaveCaptureInfo {
+                       get {
+                               return capture_context != null;
+                       }
+               }
+
+               // <summary>
+               //   Starts a new code branching.  This inherits the state of all local
+               //   variables and parameters from the current branching.
+               // </summary>
+               public FlowBranching StartFlowBranching (FlowBranching.BranchingType type, Location loc)
+               {
+                       current_flow_branching = FlowBranching.CreateBranching (CurrentBranching, type, null, loc);
+                       return current_flow_branching;
+               }
+
+               // <summary>
+               //   Starts a new code branching for block `block'.
+               // </summary>
+               public FlowBranching StartFlowBranching (Block block)
+               {
+                       FlowBranching.BranchingType type;
+
+                       if (CurrentBranching.Type == FlowBranching.BranchingType.Switch)
+                               type = FlowBranching.BranchingType.SwitchSection;
+                       else
+                               type = FlowBranching.BranchingType.Block;
+
+                       current_flow_branching = FlowBranching.CreateBranching (CurrentBranching, type, block, block.StartLocation);
+                       return current_flow_branching;
+               }
+
+               public FlowBranchingException StartFlowBranching (ExceptionStatement stmt)
+               {
+                       FlowBranchingException branching = new FlowBranchingException (
+                               CurrentBranching, stmt);
+                       current_flow_branching = branching;
+                       return branching;
+               }
+
+               // <summary>
+               //   Ends a code branching.  Merges the state of locals and parameters
+               //   from all the children of the ending branching.
+               // </summary>
+               public FlowBranching.UsageVector DoEndFlowBranching ()
+               {
+                       FlowBranching old = current_flow_branching;
+                       current_flow_branching = current_flow_branching.Parent;
+
+                       return current_flow_branching.MergeChild (old);
+               }
+
+               // <summary>
+               //   Ends a code branching.  Merges the state of locals and parameters
+               //   from all the children of the ending branching.
+               // </summary>
+               public FlowBranching.Reachability EndFlowBranching ()
+               {
+                       FlowBranching.UsageVector vector = DoEndFlowBranching ();
+
+                       return vector.Reachability;
+               }
+
+               // <summary>
+               //   Kills the current code branching.  This throws away any changed state
+               //   information and should only be used in case of an error.
+               // </summary>
+               public void KillFlowBranching ()
+               {
+                       current_flow_branching = current_flow_branching.Parent;
+               }
+
+               public void CaptureVariable (LocalInfo li)
+               {
+                       capture_context.AddLocal (CurrentAnonymousMethod, li);
+                       li.IsCaptured = true;
+               }
+
+               public void CaptureParameter (string name, Type t, int idx)
+               {
+                       
+                       capture_context.AddParameter (this, CurrentAnonymousMethod, name, t, idx);
+               }
+               
+               //
+               // Use to register a field as captured
+               //
+               public void CaptureField (FieldExpr fe)
+               {
+                       capture_context.AddField (fe);
+               }
+
+               //
+               // Whether anonymous methods have captured variables
+               //
+               public bool HaveCapturedVariables ()
+               {
+                       if (capture_context != null)
+                               return capture_context.HaveCapturedVariables;
+                       return false;
+               }
+
+               //
+               // Whether anonymous methods have captured fields or this.
+               //
+               public bool HaveCapturedFields ()
+               {
+                       if (capture_context != null)
+                               return capture_context.HaveCapturedFields;
+                       return false;
+               }
+
+               //
+               // Emits the instance pointer for the host method
+               //
+               public void EmitMethodHostInstance (EmitContext target, AnonymousMethod am)
+               {
+                       if (capture_context != null)
+                               capture_context.EmitMethodHostInstance (target, am);
+                       else if (IsStatic)
+                               target.ig.Emit (OpCodes.Ldnull);
+                       else
+                               target.ig.Emit (OpCodes.Ldarg_0);
+               }
+
+               //
+               // Returns whether the `local' variable has been captured by an anonymous
+               // method
+               //
+               public bool IsCaptured (LocalInfo local)
+               {
+                       return capture_context.IsCaptured (local);
+               }
+
+               public bool IsParameterCaptured (string name)
+               {
+                       if (capture_context != null)
+                               return capture_context.IsParameterCaptured (name);
+                       return false;
+               }
+               
+               public void EmitMeta (ToplevelBlock b, InternalParameters ip)
+               {
+                       if (capture_context != null)
+                               capture_context.EmitHelperClasses (this);
+                       b.EmitMeta (this);
+
+                       if (HasReturnLabel)
+                               ReturnLabel = ig.DefineLabel ();
+               }
+
+               public void EmitTopBlock (ToplevelBlock block, InternalParameters ip, Location loc)
+               {
+                       EmitTopBlock (block, ip, loc, "");
+               }
+
+               //
+               // Here until we can fix the problem with Mono.CSharp.Switch, which
+               // currently can not cope with ig == null during resolve (which must
+               // be fixed for switch statements to work on anonymous methods).
+               //
+               public void EmitTopBlock (ToplevelBlock block, InternalParameters ip, Location loc, string methodName)
+               {
+                       if (block == null)
+                               return;
+                       
+                       bool unreachable;
+                       
+                       if (ResolveTopBlock (null, block, ip, loc, out unreachable)){
+                               EmitMeta (block, ip);
+
+                               current_phase = Phase.Emitting;
+                               EmitResolvedTopBlock (block, unreachable);
+                       }
+               }
+
+               public bool ResolveTopBlock (EmitContext anonymous_method_host, ToplevelBlock block,
+                                            InternalParameters ip, Location loc, out bool unreachable)
+               {
+                       current_phase = Phase.Resolving;
+                       
+                       unreachable = false;
+
+                       capture_context = block.CaptureContext;
+
+                       if (!Location.IsNull (loc))
+                               CurrentFile = loc.File;
+
+#if PRODUCTION
+                           try {
+#endif
+                               int errors = Report.Errors;
+
+                               block.ResolveMeta (block, this, ip);
+
+
+                               if (Report.Errors == errors){
+                                       bool old_do_flow_analysis = DoFlowAnalysis;
+                                       DoFlowAnalysis = true;
+
+                                       if (anonymous_method_host != null)
+                                               current_flow_branching = FlowBranching.CreateBranching (
+                                               anonymous_method_host.CurrentBranching, FlowBranching.BranchingType.Block,
+                                               block, loc);
+                                       else 
+                                       current_flow_branching = FlowBranching.CreateBranching (
+                                               null, FlowBranching.BranchingType.Block, block, loc);
+
+                                       if (!block.Resolve (this)) {
+                                               current_flow_branching = null;
+                                               DoFlowAnalysis = old_do_flow_analysis;
+                                               return false;
+                                       }
+
+                                       FlowBranching.Reachability reachability = current_flow_branching.MergeTopBlock ();
+                                       current_flow_branching = null;
+
+                                       DoFlowAnalysis = old_do_flow_analysis;
+
+                                       if (reachability.AlwaysReturns ||
+                                           reachability.AlwaysThrows ||
+                                           reachability.IsUnreachable)
+                                               unreachable = true;
+                                       }
+#if PRODUCTION
+                           } catch (Exception e) {
+                                       Console.WriteLine ("Exception caught by the compiler while compiling:");
+                                       Console.WriteLine ("   Block that caused the problem begin at: " + loc);
+                                       
+                                       if (CurrentBlock != null){
+                                               Console.WriteLine ("                     Block being compiled: [{0},{1}]",
+                                                                  CurrentBlock.StartLocation, CurrentBlock.EndLocation);
+                                       }
+                                       Console.WriteLine (e.GetType ().FullName + ": " + e.Message);
+                               throw;
+                       }
+#endif
+
+                       if (ReturnType != null && !unreachable){
+                               if (!InIterator){
+                                       if (CurrentAnonymousMethod != null){
+                                               Report.Error (1643, loc, "Not all code paths return a value in anonymous method of type `{0}'",
+                                                             CurrentAnonymousMethod.Type);
+                                       } else {
+                                       Report.Error (161, loc, "Not all code paths return a value");
+                                       }
+
+                                       return false;
+                               }
+                       }
+                       block.CompleteContexts ();
+
+                       return true;
+               }
+
+               public void EmitResolvedTopBlock (ToplevelBlock block, bool unreachable)
+               {
+                       if (block != null)
+                               block.Emit (this);
+
+                       if (HasReturnLabel)
+                               ig.MarkLabel (ReturnLabel);
+
+                       if (return_value != null){
+                               ig.Emit (OpCodes.Ldloc, return_value);
+                               ig.Emit (OpCodes.Ret);
+                       } else {
+                               //
+                               // If `HasReturnLabel' is set, then we already emitted a
+                               // jump to the end of the method, so we must emit a `ret'
+                               // there.
+                               //
+                               // Unfortunately, System.Reflection.Emit automatically emits
+                               // a leave to the end of a finally block.  This is a problem
+                               // if no code is following the try/finally block since we may
+                               // jump to a point after the end of the method.
+                               // As a workaround, we're always creating a return label in
+                               // this case.
+                               //
+
+                               if ((block != null) && block.IsDestructor) {
+                                       // Nothing to do; S.R.E automatically emits a leave.
+                               } else if (HasReturnLabel || (!unreachable && !InIterator)) {
+                                       if (ReturnType != null)
+                                               ig.Emit (OpCodes.Ldloc, TemporaryReturn ());
+                                       ig.Emit (OpCodes.Ret);
+                               }
+                       }
+
+                       //
+                       // Close pending helper classes if we are the toplevel
+                       //
+                       if (capture_context != null && capture_context.ParentToplevel == null)
+                               capture_context.CloseHelperClasses ();
+               }
+
+               /// <summary>
+               ///   This is called immediately before emitting an IL opcode to tell the symbol
+               ///   writer to which source line this opcode belongs.
+               /// </summary>
+               public void Mark (Location loc, bool check_file)
+               {
+                       if ((CodeGen.SymbolWriter == null) || Location.IsNull (loc))
+                               return;
+
+                       if (check_file && (CurrentFile != loc.File))
+                               return;
+
+                       CodeGen.SymbolWriter.MarkSequencePoint (ig, loc.Row, 0);
+               }
+
+               public void DefineLocalVariable (string name, LocalBuilder builder)
+               {
+                       if (CodeGen.SymbolWriter == null)
+                               return;
+
+                       CodeGen.SymbolWriter.DefineLocalVariable (name, builder);
+               }
+
+               /// <summary>
+               ///   Returns a temporary storage for a variable of type t as 
+               ///   a local variable in the current body.
+               /// </summary>
+               public LocalBuilder GetTemporaryLocal (Type t)
+               {
+                       LocalBuilder location = null;
+                       
+                       if (temporary_storage != null){
+                               object o = temporary_storage [t];
+                               if (o != null){
+                                       if (o is ArrayList){
+                                               ArrayList al = (ArrayList) o;
+                                               
+                                               for (int i = 0; i < al.Count; i++){
+                                                       if (al [i] != null){
+                                                               location = (LocalBuilder) al [i];
+                                                               al [i] = null;
+                                                               break;
+                                                       }
+                                               }
+                                       } else
+                                               location = (LocalBuilder) o;
+                                       if (location != null)
+                                               return location;
+                               }
+                       }
+                       
+                       return ig.DeclareLocal (t);
+               }
+
+               public void FreeTemporaryLocal (LocalBuilder b, Type t)
+               {
+                       if (temporary_storage == null){
+                               temporary_storage = new Hashtable ();
+                               temporary_storage [t] = b;
+                               return;
+                       }
+                       object o = temporary_storage [t];
+                       if (o == null){
+                               temporary_storage [t] = b;
+                               return;
+                       }
+                       if (o is ArrayList){
+                               ArrayList al = (ArrayList) o;
+                               for (int i = 0; i < al.Count; i++){
+                                       if (al [i] == null){
+                                               al [i] = b;
+                                               return;
+                                       }
+                               }
+                               al.Add (b);
+                               return;
+                       }
+                       ArrayList replacement = new ArrayList ();
+                       replacement.Add (o);
+                       temporary_storage.Remove (t);
+                       temporary_storage [t] = replacement;
+               }
+
+               /// <summary>
+               ///   Current loop begin and end labels.
+               /// </summary>
+               public Label LoopBegin, LoopEnd;
+
+               /// <summary>
+               ///   Default target in a switch statement.   Only valid if
+               ///   InSwitch is true
+               /// </summary>
+               public Label DefaultTarget;
+
+               /// <summary>
+               ///   If this is non-null, points to the current switch statement
+               /// </summary>
+               public Switch Switch;
+
+               /// <summary>
+               ///   ReturnValue creates on demand the LocalBuilder for the
+               ///   return value from the function.  By default this is not
+               ///   used.  This is only required when returns are found inside
+               ///   Try or Catch statements.
+               ///
+               ///   This method is typically invoked from the Emit phase, so
+               ///   we allow the creation of a return label if it was not
+               ///   requested during the resolution phase.   Could be cleaned
+               ///   up, but it would replicate a lot of logic in the Emit phase
+               ///   of the code that uses it.
+               /// </summary>
+               public LocalBuilder TemporaryReturn ()
+               {
+                       if (return_value == null){
+                               return_value = ig.DeclareLocal (ReturnType);
+                               if (!HasReturnLabel){
+                               ReturnLabel = ig.DefineLabel ();
+                               HasReturnLabel = true;
+                       }
+                       }
+
+                       return return_value;
+               }
+
+               /// <summary>
+               ///   This method is used during the Resolution phase to flag the
+               ///   need to define the ReturnLabel
+               /// </summary>
+               public void NeedReturnLabel ()
+               {
+                       if (current_phase != Phase.Resolving){
+                               //
+                               // The reason is that the `ReturnLabel' is declared between
+                               // resolution and emission
+                               // 
+                               throw new Exception ("NeedReturnLabel called from Emit phase, should only be called during Resolve");
+                       }
+                       
+                       if (!InIterator && !HasReturnLabel) 
+                               HasReturnLabel = true;
+                       }
+
+               //
+               // Creates a field `name' with the type `t' on the proxy class
+               //
+               public FieldBuilder MapVariable (string name, Type t)
+               {
+                       if (InIterator)
+                               return CurrentIterator.MapVariable ("v_", name, t);
+
+                       throw new Exception ("MapVariable for an unknown state");
+               }
+
+               public Expression RemapParameter (int idx)
+               {
+                       FieldExpr fe = new FieldExprNoAddress (CurrentIterator.parameter_fields [idx].FieldBuilder, loc);
+                       fe.InstanceExpression = new ProxyInstance ();
+                       return fe.DoResolve (this);
+               }
+
+               public Expression RemapParameterLValue (int idx, Expression right_side)
+               {
+                       FieldExpr fe = new FieldExprNoAddress (CurrentIterator.parameter_fields [idx].FieldBuilder, loc);
+                       fe.InstanceExpression = new ProxyInstance ();
+                       return fe.DoResolveLValue (this, right_side);
+               }
+               
+               //
+               // Emits the proper object to address fields on a remapped
+               // variable/parameter to field in anonymous-method/iterator proxy classes.
+               //
+               public void EmitThis ()
+               {
+                       ig.Emit (OpCodes.Ldarg_0);
+                       if (InIterator){
+                               if (!IsStatic){
+                               FieldBuilder this_field = CurrentIterator.this_field.FieldBuilder;
+                               if (TypeManager.IsValueType (this_field.FieldType))
+                                       ig.Emit (OpCodes.Ldflda, this_field);
+                               else
+                                       ig.Emit (OpCodes.Ldfld, this_field);
+                       }
+                       } else if (capture_context != null && CurrentAnonymousMethod != null){
+                               ScopeInfo si = CurrentAnonymousMethod.Scope;
+                               while (si != null){
+                                       if (si.ParentLink != null)
+                                               ig.Emit (OpCodes.Ldfld, si.ParentLink);
+                                       if (si.THIS != null){
+                                               ig.Emit (OpCodes.Ldfld, si.THIS);
+                                               break;
+                                       }
+                                       si = si.ParentScope;
+                               }
+                       } 
+               }
+
+               //
+               // Emits the code necessary to load the instance required
+               // to access the captured LocalInfo
+               //
+               public void EmitCapturedVariableInstance (LocalInfo li)
+               {
+                       if (RemapToProxy){
+                               ig.Emit (OpCodes.Ldarg_0);
+                               return;
+                       }
+                       
+                       if (capture_context == null)
+                               throw new Exception ("Calling EmitCapturedContext when there is no capture_context");
+                       
+                       capture_context.EmitCapturedVariableInstance (this, li, CurrentAnonymousMethod);
+               }
+
+               public void EmitParameter (string name)
+               {
+                       capture_context.EmitParameter (this, name);
+               }
+
+               public void EmitAssignParameter (string name, Expression source, bool leave_copy, bool prepare_for_load)
+               {
+                       capture_context.EmitAssignParameter (this, name, source, leave_copy, prepare_for_load);
+               }
+
+               public void EmitAddressOfParameter (string name)
+               {
+                       capture_context.EmitAddressOfParameter (this, name);
+               }
+
+               public Expression GetThis (Location loc)
+               {
+                       This my_this;
+                       if (CurrentBlock != null)
+                               my_this = new This (CurrentBlock, loc);
+                       else
+                               my_this = new This (loc);
+
+                       if (!my_this.ResolveBase (this))
+                               my_this = null;
+
+                       return my_this;
+               }
+       }
+
+
+       public abstract class CommonAssemblyModulClass: Attributable {
+               protected CommonAssemblyModulClass ():
+                       base (null)
+               {
+               }
+
+               public void AddAttribute (Attribute attr)
+               {
+                       if (OptAttributes == null) {
+                               OptAttributes = new Attributes (attr);
+                               return;
+                       }
+                       OptAttributes.AddAttribute (attr);
+               }
+
+               public void AddAttributes (ArrayList attrs)
+               {
+                       if (OptAttributes == null) {
+                               OptAttributes = new Attributes (attrs);
+                               return;
+                       }
+                       OptAttributes.AddAttributes (attrs);
+               }
+
+               public virtual void Emit (TypeContainer tc) 
+               {
+                       if (OptAttributes == null)
+                               return;
+
+                       EmitContext ec = new EmitContext (tc, Mono.CSharp.Location.Null, null, null, 0, false);
+                       OptAttributes.Emit (ec, this);
+               }
+
+               protected Attribute GetClsCompliantAttribute ()
+               {
+                       if (OptAttributes == null)
+                               return null;
+
+                       EmitContext temp_ec = new EmitContext (RootContext.Tree.Types, Mono.CSharp.Location.Null, null, null, 0, false);
+                       Attribute a = OptAttributes.Search (TypeManager.cls_compliant_attribute_type, temp_ec);
+                       if (a != null) {
+                               a.Resolve (temp_ec);
+                       }
+                       return a;
+               }
+       }
+
+       public class AssemblyClass: CommonAssemblyModulClass {
+               // TODO: make it private and move all builder based methods here
+               public AssemblyBuilder Builder;
+                    
+               bool is_cls_compliant;
+
+               ListDictionary declarative_security;
+
+               static string[] attribute_targets = new string [] { "assembly" };
+
+               public AssemblyClass (): base ()
+               {
+                       is_cls_compliant = false;
+               }
+
+               public bool IsClsCompliant {
+                       get {
+                               return is_cls_compliant;
+                       }
+                       }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Assembly;
+                       }
+               }
+
+               public override bool IsClsCompliaceRequired(DeclSpace ds)
+               {
+                       return is_cls_compliant;
+               }
+
+               public void ResolveClsCompliance ()
+               {
+                       Attribute a = GetClsCompliantAttribute ();
+                       if (a == null)
+                               return;
+
+                       is_cls_compliant = a.GetClsCompliantAttributeValue (null);
+               }
+
+               // fix bug #56621
+               private void SetPublicKey (AssemblyName an, byte[] strongNameBlob) 
+               {
+                       try {
+                               // check for possible ECMA key
+                               if (strongNameBlob.Length == 16) {
+                                       // will be rejected if not "the" ECMA key
+                                       an.SetPublicKey (strongNameBlob);
+                               }
+                               else {
+                                       // take it, with or without, a private key
+                                       RSA rsa = CryptoConvert.FromCapiKeyBlob (strongNameBlob);
+                                       // and make sure we only feed the public part to Sys.Ref
+                                       byte[] publickey = CryptoConvert.ToCapiPublicKeyBlob (rsa);
+                                       
+                                       // AssemblyName.SetPublicKey requires an additional header
+                                       byte[] publicKeyHeader = new byte [12] { 0x00, 0x24, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x94, 0x00, 0x00, 0x00 };
+
+                                       byte[] encodedPublicKey = new byte [12 + publickey.Length];
+                                       Buffer.BlockCopy (publicKeyHeader, 0, encodedPublicKey, 0, 12);
+                                       Buffer.BlockCopy (publickey, 0, encodedPublicKey, 12, publickey.Length);
+                                       an.SetPublicKey (encodedPublicKey);
+                               }
+                       }
+                       catch (Exception) {
+                               Report.Error (1548, "Could not strongname the assembly. File `" +
+                                       RootContext.StrongNameKeyFile + "' incorrectly encoded.");
+                               Environment.Exit (1);
+                       }
+               }
+
+               // TODO: rewrite this code (to kill N bugs and make it faster) and use standard ApplyAttribute way.
+               public AssemblyName GetAssemblyName (string name, string output) 
+               {
+                       if (OptAttributes != null) {
+                               foreach (Attribute a in OptAttributes.Attrs) {
+                                      // cannot rely on any resolve-based members before you call Resolve
+                                      if (a.ExplicitTarget == null || a.ExplicitTarget != "assembly")
+                                              continue;
+
+                                       // TODO: This code is buggy: comparing Attribute name without resolving it is wrong.
+                                       //       However, this is invoked by CodeGen.Init, at which time none of the namespaces
+                                       //       are loaded yet.
+                                       switch (a.Name) {
+                                               case "AssemblyKeyFile":
+                                               case "AssemblyKeyFileAttribute":
+                                               case "System.Reflection.AssemblyKeyFileAttribute":
+                                                       if (RootContext.StrongNameKeyFile != null) {
+                                                               Report.SymbolRelatedToPreviousError (a.Location, a.Name);
+                                                               Report.Warning (1616, "Compiler option '{0}' overrides '{1}' given in source", "keyfile", "System.Reflection.AssemblyKeyFileAttribute");
+                                                       }
+                                                       else {
+                                                               string value = a.GetString ();
+                                                               if (value != String.Empty)
+                                                                       RootContext.StrongNameKeyFile = value;
+                                                       }
+                                                       break;
+                                               case "AssemblyKeyName":
+                                               case "AssemblyKeyNameAttribute":
+                                               case "System.Reflection.AssemblyKeyNameAttribute":
+                                                       if (RootContext.StrongNameKeyContainer != null) {
+                                                               Report.SymbolRelatedToPreviousError (a.Location, a.Name);
+                                                               Report.Warning (1616, "keycontainer", "Compiler option '{0}' overrides '{1}' given in source", "System.Reflection.AssemblyKeyNameAttribute");
+                                                       }
+                                                       else {
+                                                               string value = a.GetString ();
+                                                               if (value != String.Empty)
+                                                                       RootContext.StrongNameKeyContainer = value;
+                                                       }
+                                                       break;
+                                               case "AssemblyDelaySign":
+                                               case "AssemblyDelaySignAttribute":
+                                               case "System.Reflection.AssemblyDelaySignAttribute":
+                                                       RootContext.StrongNameDelaySign = a.GetBoolean ();
+                                                       break;
+                                       }
+                               }
+                       }
+
+                       AssemblyName an = new AssemblyName ();
+                       an.Name = Path.GetFileNameWithoutExtension (name);
+
+                       // note: delay doesn't apply when using a key container
+                       if (RootContext.StrongNameKeyContainer != null) {
+                               an.KeyPair = new StrongNameKeyPair (RootContext.StrongNameKeyContainer);
+                               return an;
+                       }
+
+                       // strongname is optional
+                       if (RootContext.StrongNameKeyFile == null)
+                               return an;
+
+                       string AssemblyDir = Path.GetDirectoryName (output);
+
+                       // the StrongName key file may be relative to (a) the compiled
+                       // file or (b) to the output assembly. See bugzilla #55320
+                       // http://bugzilla.ximian.com/show_bug.cgi?id=55320
+
+                       // (a) relative to the compiled file
+                       string filename = Path.GetFullPath (RootContext.StrongNameKeyFile);
+                       bool exist = File.Exists (filename);
+                       if ((!exist) && (AssemblyDir != null) && (AssemblyDir != String.Empty)) {
+                               // (b) relative to the outputed assembly
+                               filename = Path.GetFullPath (Path.Combine (AssemblyDir, RootContext.StrongNameKeyFile));
+                               exist = File.Exists (filename);
+                       }
+
+                       if (exist) {
+                               using (FileStream fs = new FileStream (filename, FileMode.Open, FileAccess.Read)) {
+                                       byte[] snkeypair = new byte [fs.Length];
+                                       fs.Read (snkeypair, 0, snkeypair.Length);
+
+                                       if (RootContext.StrongNameDelaySign) {
+                                               // delayed signing - DO NOT include private key
+                                               SetPublicKey (an, snkeypair);
+                                       }
+                                       else {
+                                               // no delay so we make sure we have the private key
+                                               try {
+                                                       CryptoConvert.FromCapiPrivateKeyBlob (snkeypair);
+                                                       an.KeyPair = new StrongNameKeyPair (snkeypair);
+                                               }
+                                               catch (CryptographicException) {
+                                                       if (snkeypair.Length == 16) {
+                                                               // error # is different for ECMA key
+                                                               Report.Error (1606, "Could not strongname the assembly. " + 
+                                                                       "ECMA key can only be used to delay-sign assemblies");
+                                                       }
+                                                       else {
+                                                               Report.Error (1548, "Could not strongname the assembly. File `" +
+                                                                       RootContext.StrongNameKeyFile +
+                                                                       "' doesn't have a private key.");
+                                                       }
+                                                       Environment.Exit (1);
+                                               }
+                                       }
+                               }
+                       }
+                       else {
+                               Report.Error (1548, "Could not strongname the assembly. File `" +
+                                       RootContext.StrongNameKeyFile + "' not found.");
+                               Environment.Exit (1);
+                       }
+                       return an;
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder)
+               {
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (true)) {
+                               if (declarative_security == null)
+                                       declarative_security = new ListDictionary ();
+
+                               a.ExtractSecurityPermissionSet (declarative_security);
+                               return;
+                       }
+
+                       Builder.SetCustomAttribute (customBuilder);
+               }
+
+               public override void Emit (TypeContainer tc)
+               {
+                       base.Emit (tc);
+
+                       if (declarative_security != null) {
+
+                               MethodInfo add_permission = typeof (AssemblyBuilder).GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic);
+                               object builder_instance = Builder;
+
+                               try {
+                                       // Microsoft runtime hacking
+                                       if (add_permission == null) {
+                                               Type assembly_builder = typeof (AssemblyBuilder).Assembly.GetType ("System.Reflection.Emit.AssemblyBuilderData");
+                                               add_permission = assembly_builder.GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic);
+
+                                               FieldInfo fi = typeof (AssemblyBuilder).GetField ("m_assemblyData", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
+                                               builder_instance = fi.GetValue (Builder);
+                                       }
+
+                                       object[] args = new object [] { declarative_security [SecurityAction.RequestMinimum],
+                                                                                                 declarative_security [SecurityAction.RequestOptional],
+                                                                                                 declarative_security [SecurityAction.RequestRefuse] };
+                                       add_permission.Invoke (builder_instance, args);
+                               }
+                               catch {
+                                       Report.RuntimeMissingSupport (Location.Null, "assembly permission setting");
+                               }
+                       }
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+       }
+
+       public class ModuleClass: CommonAssemblyModulClass {
+               // TODO: make it private and move all builder based methods here
+               public ModuleBuilder Builder;
+               bool m_module_is_unsafe;
+
+               static string[] attribute_targets = new string [] { "module" };
+
+               public ModuleClass (bool is_unsafe)
+               {
+                       m_module_is_unsafe = is_unsafe;
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Module;
+                       }
+               }
+
+               public override bool IsClsCompliaceRequired(DeclSpace ds)
+               {
+                       return CodeGen.Assembly.IsClsCompliant;
+                       }
+
+               public override void Emit (TypeContainer tc) 
+               {
+                       base.Emit (tc);
+
+                       if (!m_module_is_unsafe)
+                               return;
+
+                       if (TypeManager.unverifiable_code_ctor == null) {
+                               Console.WriteLine ("Internal error ! Cannot set unverifiable code attribute.");
+                               return;
+                       }
+                               
+                       ApplyAttributeBuilder (null, new CustomAttributeBuilder (TypeManager.unverifiable_code_ctor, new object [0]));
+               }
+                
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder)
+               {
+                       if (a != null && a.Type == TypeManager.cls_compliant_attribute_type) {
+                               Report.Warning (3012, a.Location, "You must specify the CLSCompliant attribute on the assembly, not the module, to enable CLS compliance checking");
+                       }
+
+                       Builder.SetCustomAttribute (customBuilder);
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+       }
+}
diff --git a/mcs/bmcs/const.cs b/mcs/bmcs/const.cs
new file mode 100644 (file)
index 0000000..1c15f85
--- /dev/null
@@ -0,0 +1,305 @@
+//
+// const.cs: Constant declarations.
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//   Marek Safar (marek.safar@seznam.cz)
+//
+// (C) 2001 Ximian, Inc.
+//
+//
+
+//
+// This is needed because the following situation arises:
+//
+//     The FieldBuilder is declared with the real type for an enumeration
+//
+//     When we attempt to set the value for the constant, the FieldBuilder.SetConstant
+//     function aborts because it requires its argument to be of the same type
+//
+
+namespace Mono.CSharp {
+
+       using System;
+       using System.Reflection;
+       using System.Reflection.Emit;
+       using System.Collections;
+
+       public class Const : FieldMember {
+               public Expression Expr;
+               EmitContext const_ec;
+
+               bool resolved = false;
+               object ConstantValue = null;
+
+               bool in_transit = false;
+
+               public const int AllowedModifiers =
+                       Modifiers.NEW |
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE;
+
+               public Const (TypeContainer parent, Expression constant_type, string name,
+                             Expression expr, int mod_flags, Attributes attrs, Location loc)
+                       : base (parent, constant_type, mod_flags, AllowedModifiers,
+                               new MemberName (name), null, attrs, loc)
+               {
+                       Expr = expr;
+                       ModFlags |= Modifiers.STATIC;
+               }
+
+#if DEBUG
+               void dump_tree (Type t)
+               {
+                       Console.WriteLine ("Dumping hierarchy");
+                       while (t != null){
+                               Console.WriteLine ("   " + t.FullName + " " +
+                                       (t.GetType ().IsEnum ? "yes" : "no"));
+                               t = t.BaseType;
+                       }
+               }
+#endif
+
+               /// <summary>
+               ///   Defines the constant in the @parent
+               /// </summary>
+               public override bool Define ()
+               {
+                       if (!base.Define ())
+                               return false;
+
+                       const_ec = new EmitContext (Parent, Location, null, MemberType, ModFlags);
+
+                       Type ttype = MemberType;
+                       while (ttype.IsArray)
+                           ttype = TypeManager.GetElementType (ttype);
+                       
+                       if (!TypeManager.IsBuiltinType(ttype) && (!ttype.IsSubclassOf(TypeManager.enum_type)) && !(Expr is NullLiteral)){
+                               Report.Error (
+                                       -3, Location,
+                                       "Constant type is not valid (only system types are allowed)");
+                               return false;
+                       }
+
+                       FieldAttributes field_attr = FieldAttributes.Static | Modifiers.FieldAttr (ModFlags);
+                       // I don't know why but they emit decimal constant as InitOnly
+                       if (ttype == TypeManager.decimal_type) {
+                               field_attr |= FieldAttributes.InitOnly;
+                       }
+                       else {
+                               field_attr |= FieldAttributes.Literal;
+                       }
+
+                       FieldBuilder = Parent.TypeBuilder.DefineField (Name, MemberType, field_attr);
+
+                       TypeManager.RegisterConstant (FieldBuilder, this);
+
+                       return true;
+               }
+
+               //
+               // Changes the type of the constant expression `expr' to the Type `type'
+               // Returns null on failure.
+               //
+               public static Constant ChangeType (Location loc, Constant expr, Type type)
+               {
+                       if (type == TypeManager.object_type)
+                               return expr;
+
+                       bool fail;
+
+                       // from the null type to any reference-type.
+                       if (expr.Type == TypeManager.null_type && !type.IsValueType && !TypeManager.IsEnumType (type))
+                               return NullLiteral.Null;
+
+                       if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, expr, type)){
+                               Convert.Error_CannotImplicitConversion (loc, expr.Type, type);
+                               return null;
+                       }
+
+                       // Special-case: The 0 literal can be converted to an enum value,
+                       // and ImplicitStandardConversionExists will return true in that case.
+                       if (expr.Type == TypeManager.int32_type && TypeManager.IsEnumType (type)){
+                               if (expr is IntLiteral && ((IntLiteral) expr).Value == 0)
+                                       return new EnumConstant (expr, type);
+                       }
+                       
+                       object constant_value = TypeManager.ChangeType (expr.GetValue (), type, out fail);
+                       if (fail){
+                               Convert.Error_CannotImplicitConversion (loc, expr.Type, type);
+                               
+                               //
+                               // We should always catch the error before this is ever
+                               // reached, by calling Convert.ImplicitStandardConversionExists
+                               //
+                               throw new Exception (
+                                                    String.Format ("LookupConstantValue: This should never be reached {0} {1}", expr.Type, type));
+                       }
+
+                       Constant retval;
+                       if (type == TypeManager.int32_type)
+                               retval = new IntConstant ((int) constant_value);
+                       else if (type == TypeManager.uint32_type)
+                               retval = new UIntConstant ((uint) constant_value);
+                       else if (type == TypeManager.int64_type)
+                               retval = new LongConstant ((long) constant_value);
+                       else if (type == TypeManager.uint64_type)
+                               retval = new ULongConstant ((ulong) constant_value);
+                       else if (type == TypeManager.float_type)
+                               retval = new FloatConstant ((float) constant_value);
+                       else if (type == TypeManager.double_type)
+                               retval = new DoubleConstant ((double) constant_value);
+                       else if (type == TypeManager.string_type)
+                               retval = new StringConstant ((string) constant_value);
+                       else if (type == TypeManager.short_type)
+                               retval = new ShortConstant ((short) constant_value);
+                       else if (type == TypeManager.ushort_type)
+                               retval = new UShortConstant ((ushort) constant_value);
+                       else if (type == TypeManager.sbyte_type)
+                               retval = new SByteConstant ((sbyte) constant_value);
+                       else if (type == TypeManager.byte_type)
+                               retval = new ByteConstant ((byte) constant_value);
+                       else if (type == TypeManager.char_type)
+                               retval = new CharConstant ((char) constant_value);
+                       else if (type == TypeManager.bool_type)
+                               retval = new BoolConstant ((bool) constant_value);
+                       else if (type == TypeManager.decimal_type)
+                               retval = new DecimalConstant ((decimal) constant_value);
+                       else
+                               throw new Exception ("LookupConstantValue: Unhandled constant type: " + type);
+                       
+                       return retval;
+               }
+               
+               /// <summary>
+               ///  Looks up the value of a constant field. Defines it if it hasn't
+               ///  already been. Similar to LookupEnumValue in spirit.
+               /// </summary>
+               public bool LookupConstantValue (out object value)
+               {
+                       if (resolved) {
+                               value = ConstantValue;
+                               return true;
+                       }
+
+                       if (in_transit) {
+                               Report.Error (110, Location,
+                                             "The evaluation of the constant value for `" +
+                                             Name + "' involves a circular definition.");
+                               value = null;
+                               return false;
+                       }
+
+                       in_transit = true;
+                       int errors = Report.Errors;
+
+                       //
+                       // We might have cleared Expr ourselves in a recursive definition
+                       //
+                       if (Expr == null){
+                               value = null;
+                               return false;
+                       }
+
+                       Expr = Expr.Resolve (const_ec);
+
+                       in_transit = false;
+
+                       if (Expr == null) {
+                               if (errors == Report.Errors)
+                                       Report.Error (150, Location, "A constant value is expected");
+                               value = null;
+                               return false;
+                       }
+
+                       Expression real_expr = Expr;
+
+                       Constant ce = Expr as Constant;
+                       if (ce == null){
+                               UnCheckedExpr un_expr = Expr as UnCheckedExpr;
+                               CheckedExpr ch_expr = Expr as CheckedExpr;
+                               EmptyCast ec_expr = Expr as EmptyCast;
+
+                               if ((un_expr != null) && (un_expr.Expr is Constant))
+                                       Expr = un_expr.Expr;
+                               else if ((ch_expr != null) && (ch_expr.Expr is Constant))
+                                       Expr = ch_expr.Expr;
+                               else if ((ec_expr != null) && (ec_expr.Child is Constant))
+                                       Expr = ec_expr.Child;
+                               else if (Expr is ArrayCreation){
+                                       Report.Error (133, Location, "Arrays can not be constant");
+                               } else {
+                                       if (errors == Report.Errors)
+                                               Report.Error (150, Location, "A constant value is expected");
+                                       value = null;
+                                       return false;
+                               }
+
+                               ce = Expr as Constant;
+                       }
+
+                       if (MemberType != real_expr.Type) {
+                               ce = ChangeType (Location, ce, MemberType);
+                               if (ce == null){
+                                       value = null;
+                                       return false;
+                               }
+                               Expr = ce;
+                       }
+                       ConstantValue = ce.GetValue ();
+
+                       if (MemberType.IsEnum){
+                               //
+                               // This sadly does not work for our user-defined enumerations types ;-(
+                               //
+                               try {
+                                       ConstantValue = System.Enum.ToObject (
+                                               MemberType, ConstantValue);
+                               } catch (ArgumentException){
+                                       Report.Error (
+                                               -16, Location,
+                                               ".NET SDK 1.0 does not permit to create the constant "+
+                                               " field from a user-defined enumeration");
+                               }
+                       }
+
+                       if (ce is DecimalConstant) {
+                               Decimal d = ((DecimalConstant)ce).Value;
+                               int[] bits = Decimal.GetBits (d);
+                               object[] args = new object[] { (byte)(bits [3] >> 16), (byte)(bits [3] >> 31), (uint)bits [2], (uint)bits [1], (uint)bits [0] };
+                               CustomAttributeBuilder cab = new CustomAttributeBuilder (TypeManager.decimal_constant_attribute_ctor, args);
+                               FieldBuilder.SetCustomAttribute (cab);
+                       }
+                       else{
+                               FieldBuilder.SetConstant (ConstantValue);
+                       }
+
+                       if (!TypeManager.RegisterFieldValue (FieldBuilder, ConstantValue))
+                               throw new Exception ("Cannot register const value");
+
+                       value = ConstantValue;
+                       resolved = true;
+                       return true;
+               }
+               
+               
+               /// <summary>
+               ///  Emits the field value by evaluating the expression
+               /// </summary>
+               public override void Emit ()
+               {
+                       object value;
+                       LookupConstantValue (out value);
+
+                       if (OptAttributes != null) {
+                               OptAttributes.Emit (const_ec, this);
+                       }
+
+                       base.Emit ();
+               }
+       }
+}
+
+
diff --git a/mcs/bmcs/constant.cs b/mcs/bmcs/constant.cs
new file mode 100644 (file)
index 0000000..73de93f
--- /dev/null
@@ -0,0 +1,1142 @@
+//
+// constant.cs: Constants.
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+//
+
+namespace Mono.CSharp {
+
+       using System;
+       using System.Reflection.Emit;
+
+       /// <summary>
+       ///   Base class for constants and literals.
+       /// </summary>
+       public abstract class Constant : Expression {
+               /// <remarks>
+               ///   This is different from ToString in that ToString
+               ///   is supposed to be there for debugging purposes,
+               ///   and is not guaranteed to be useful for anything else,
+               ///   AsString() will provide something that can be used
+               ///   for round-tripping C# code.  Maybe it can be used
+               ///   for IL assembly as well.
+               /// </remarks>
+               public abstract string AsString ();
+
+               override public string ToString ()
+               {
+                       return this.GetType ().Name + " (" + AsString () + ")";
+               }
+
+               /// <summary>
+               ///  This is used to obtain the actual value of the literal
+               ///  cast into an object.
+               /// </summary>
+               public abstract object GetValue ();
+
+               /// <summary>
+               ///   Constants are always born in a fully resolved state
+               /// </summary>
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       return this;
+               }
+
+               //
+               // The various ToXXXX conversion functions are used by the constant
+               // folding evaluator.   A null value is returned if the conversion is
+               // not possible.   
+               //
+               // Note: not all the patterns for catching `implicit_conv' are the same.
+               // some implicit conversions can never be performed between two types
+               // even if the conversion would be lossless (for example short to uint),
+               // but some conversions are explicitly permitted by the standard provided
+               // that there will be no loss of information (for example, int to uint).
+               //
+               public DoubleConstant ToDouble (Location loc)
+               {
+                       DoubleConstant c = ConvertToDouble ();
+
+                       if (c == null)
+                               Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.double_type);
+
+                       return c;
+               }
+
+               public FloatConstant ToFloat (Location loc)
+               {
+                       FloatConstant c = ConvertToFloat ();
+
+                       if (c == null)
+                               Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.float_type);
+
+                       return c;
+               }
+
+               public ULongConstant ToULong (Location loc)
+               {
+                       ULongConstant c = ConvertToULong ();
+
+                       if (c == null)
+                               Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.uint64_type);
+
+                       return c;
+               }
+
+               public LongConstant ToLong (Location loc)
+               {
+                       LongConstant c = ConvertToLong ();
+
+                       if (c == null)
+                               Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.int64_type);
+
+                       return c;
+               }
+               
+               public UIntConstant ToUInt (Location loc)
+               {
+                       UIntConstant c = ConvertToUInt ();
+
+                       if (c == null)
+                               Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.uint32_type);
+
+                       return c;
+               }
+
+               public IntConstant ToInt (Location loc)
+               {
+                       IntConstant c = ConvertToInt ();
+
+                       if (c == null)
+                               Convert.Error_CannotImplicitConversion (loc, Type, TypeManager.int32_type);
+
+                       return c;
+               }
+
+               public DecimalConstant ToDecimal (Location loc)
+               {
+                       DecimalConstant c = ConvertToDecimal ();
+
+                       if (c == null)
+                               Convert.Error_CannotConvertType (loc, Type, TypeManager.decimal_type);
+
+                       return c;
+               }
+
+               public virtual DecimalConstant ConvertToDecimal ()
+               {
+                       return null;
+               }
+               
+               public virtual DoubleConstant ConvertToDouble ()
+               {
+                       return null;
+               }
+
+               public virtual FloatConstant ConvertToFloat ()
+               {
+                       return null;
+               }
+
+               public virtual ULongConstant ConvertToULong ()
+               {
+                       return null;
+               }
+
+               public virtual LongConstant ConvertToLong ()
+               {
+                       return null;
+               }
+
+               public virtual UIntConstant ConvertToUInt ()
+               {
+                       return null;
+               }
+
+               public virtual IntConstant ConvertToInt ()
+               {
+                       return null;
+               }
+               
+               public abstract bool IsNegative {
+                       get;
+               }
+
+               //
+               // Returns true iff 1) the stack type of this is one of Object, 
+               // int32, int64 and 2) this == 0 or this == null.
+               //
+               public virtual bool IsZeroInteger {
+                       get { return false; }
+               }
+       }
+       
+       public class BoolConstant : Constant {
+               public readonly bool Value;
+               
+               public BoolConstant (bool val)
+               {
+                       type = TypeManager.bool_type;
+                       eclass = ExprClass.Value;
+
+                       Value = val;
+               }
+
+               override public string AsString ()
+               {
+                       return Value ? "true" : "false";
+               }
+
+               public override object GetValue ()
+               {
+                       return (object) Value;
+               }
+                               
+               
+               public override void Emit (EmitContext ec)
+               {
+                       if (Value)
+                               ec.ig.Emit (OpCodes.Ldc_I4_1);
+                       else
+                               ec.ig.Emit (OpCodes.Ldc_I4_0);
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+       
+               public override bool IsZeroInteger {
+                       get { return Value == false; }
+               }
+       }
+
+       public class ByteConstant : Constant {
+               public readonly byte Value;
+
+               public ByteConstant (byte v)
+               {
+                       type = TypeManager.byte_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       IntLiteral.EmitInt (ec.ig, Value);
+               }
+
+               public override string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return new DoubleConstant (Value);
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return new FloatConstant (Value);
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       return new ULongConstant (Value);
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return new LongConstant (Value);
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return new UIntConstant (Value);
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return new IntConstant (Value);
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+
+               public override bool IsZeroInteger {
+                       get { return Value == 0; }
+               }
+       }
+
+       public class CharConstant : Constant {
+               public readonly char Value;
+
+               public CharConstant (char v)
+               {
+                       type = TypeManager.char_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       IntLiteral.EmitInt (ec.ig, Value);
+               }
+
+               static public string descape (char c)
+               {
+                       switch (c){
+                       case '\a':
+                               return "\\a"; 
+                       case '\b':
+                               return "\\b"; 
+                       case '\n':
+                               return "\\n"; 
+                       case '\t':
+                               return "\\t"; 
+                       case '\v':
+                               return "\\v"; 
+                       case '\r':
+                               return "\\r"; 
+                       case '\\':
+                               return "\\\\";
+                       case '\f':
+                               return "\\f"; 
+                       case '\0':
+                               return "\\0"; 
+                       case '"':
+                               return "\\\""; 
+                       case '\'':
+                               return "\\\'"; 
+                       }
+                       return c.ToString ();
+               }
+
+               public override string AsString ()
+               {
+                       return "\"" + descape (Value) + "\"";
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return new DoubleConstant (Value);
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return new FloatConstant (Value);
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       return new ULongConstant (Value);
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return new LongConstant (Value);
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return new UIntConstant (Value);
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return new IntConstant (Value);
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+
+               public override bool IsZeroInteger {
+                       get { return Value == '\0'; }
+               }
+       }
+
+       public class SByteConstant : Constant {
+               public readonly sbyte Value;
+
+               public SByteConstant (sbyte v)
+               {
+                       type = TypeManager.sbyte_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       IntLiteral.EmitInt (ec.ig, Value);
+               }
+
+               public override string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return new DoubleConstant (Value);
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return new FloatConstant (Value);
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       if (Value >= 0)
+                               return new ULongConstant ((ulong) Value);
+                       
+                       return null;
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return new LongConstant (Value);
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return null;
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return new IntConstant (Value);
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return Value < 0;
+                       }
+               }
+               
+               public override bool IsZeroInteger {
+                       get { return Value == 0; }
+               }
+       }
+
+       public class ShortConstant : Constant {
+               public readonly short Value;
+
+               public ShortConstant (short v)
+               {
+                       type = TypeManager.short_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       IntLiteral.EmitInt (ec.ig, Value);
+               }
+
+               public override string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return new DoubleConstant (Value);
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return new FloatConstant (Value);
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       return null;
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return new LongConstant (Value);
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return null;
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return new IntConstant (Value);
+               }
+               
+               public override bool IsZeroInteger {
+                       get { return Value == 0; }
+               }
+
+               public override bool IsNegative {
+                       get {
+                               return Value < 0;
+                       }
+               }
+       }
+
+       public class UShortConstant : Constant {
+               public readonly ushort Value;
+
+               public UShortConstant (ushort v)
+               {
+                       type = TypeManager.ushort_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       IntLiteral.EmitInt (ec.ig, Value);
+               }
+
+               public override string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return new DoubleConstant (Value);
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return new FloatConstant (Value);
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       return new ULongConstant (Value);
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return new LongConstant (Value);
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return new UIntConstant (Value);
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return new IntConstant (Value);
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+       
+               public override bool IsZeroInteger {
+                       get { return Value == 0; }
+               }
+       }
+
+       public class IntConstant : Constant {
+               public readonly int Value;
+
+               public IntConstant (int v)
+               {
+                       type = TypeManager.int32_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               static public void EmitInt (ILGenerator ig, int i)
+               {
+                       switch (i){
+                       case -1:
+                               ig.Emit (OpCodes.Ldc_I4_M1);
+                               break;
+                               
+                       case 0:
+                               ig.Emit (OpCodes.Ldc_I4_0);
+                               break;
+                               
+                       case 1:
+                               ig.Emit (OpCodes.Ldc_I4_1);
+                               break;
+                               
+                       case 2:
+                               ig.Emit (OpCodes.Ldc_I4_2);
+                               break;
+                               
+                       case 3:
+                               ig.Emit (OpCodes.Ldc_I4_3);
+                               break;
+                               
+                       case 4:
+                               ig.Emit (OpCodes.Ldc_I4_4);
+                               break;
+                               
+                       case 5:
+                               ig.Emit (OpCodes.Ldc_I4_5);
+                               break;
+                               
+                       case 6:
+                               ig.Emit (OpCodes.Ldc_I4_6);
+                               break;
+                               
+                       case 7:
+                               ig.Emit (OpCodes.Ldc_I4_7);
+                               break;
+                               
+                       case 8:
+                               ig.Emit (OpCodes.Ldc_I4_8);
+                               break;
+
+                       default:
+                               if (i >= -128 && i <= 127){
+                                       ig.Emit (OpCodes.Ldc_I4_S, (sbyte) i);
+                               } else
+                                       ig.Emit (OpCodes.Ldc_I4, i);
+                               break;
+                       }
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       EmitInt (ec.ig, Value);
+               }
+
+               public override string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DecimalConstant ConvertToDecimal()
+               {
+                       return new DecimalConstant (Value);
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return new DoubleConstant (Value);
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return new FloatConstant (Value);
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       if (Value < 0)
+                               return null;
+
+                       return new ULongConstant ((ulong) Value);
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return new LongConstant (Value);
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       if (Value < 0)
+                               return null;
+
+                       return new UIntConstant ((uint) Value);
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return this;
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return Value < 0;
+                       }
+               }
+
+               public override bool IsZeroInteger {
+                       get { return Value == 0; }
+               }
+       }
+
+       public class UIntConstant : Constant {
+               public readonly uint Value;
+
+               public UIntConstant (uint v)
+               {
+                       type = TypeManager.uint32_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       IntLiteral.EmitInt (ec.ig, unchecked ((int) Value));
+               }
+
+               public override string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return new DoubleConstant (Value);
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return new FloatConstant (Value);
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       return new ULongConstant (Value);
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return new LongConstant (Value);
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return this;
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return null;
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+
+               public override bool IsZeroInteger {
+                       get { return Value == 0; }
+               }
+       }
+
+       public class LongConstant : Constant {
+               public readonly long Value;
+
+               public LongConstant (long v)
+               {
+                       type = TypeManager.int64_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       EmitLong (ig, Value);
+               }
+
+               static public void EmitLong (ILGenerator ig, long l)
+               {
+                       if ((l >> 32) == 0){
+                               IntLiteral.EmitInt (ig, unchecked ((int) l));
+                               ig.Emit (OpCodes.Conv_U8);
+                       } else {
+                               ig.Emit (OpCodes.Ldc_I8, l);
+                       }
+               }
+
+               public override string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return new DoubleConstant (Value);
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return new FloatConstant (Value);
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       if (Value < 0)
+                               return null;
+                       
+                       return new ULongConstant ((ulong) Value);
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return this;
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return null;
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return null;
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return Value < 0;
+                       }
+               }
+
+               public override bool IsZeroInteger {
+                       get { return Value == 0; }
+               }
+       }
+
+       public class ULongConstant : Constant {
+               public readonly ulong Value;
+
+               public ULongConstant (ulong v)
+               {
+                       type = TypeManager.uint64_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       LongLiteral.EmitLong (ig, unchecked ((long) Value));
+               }
+
+               public override string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return new DoubleConstant (Value);
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return new FloatConstant (Value);
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       return this;
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return null;
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return null;
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return null;
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+
+               public override bool IsZeroInteger {
+                       get { return Value == 0; }
+               }
+       }
+
+       public class FloatConstant : Constant {
+               public readonly float Value;
+
+               public FloatConstant (float v)
+               {
+                       type = TypeManager.float_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ec.ig.Emit (OpCodes.Ldc_R4, Value);
+               }
+
+               public override string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return new DoubleConstant (Value);
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return this;
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return null;
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return null;
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return null;
+               }
+
+               public override bool IsNegative {
+                       get {
+                               return Value < 0;
+                       }
+               }
+       }
+
+       public class DoubleConstant : Constant {
+               public readonly double Value;
+
+               public DoubleConstant (double v)
+               {
+                       type = TypeManager.double_type;
+                       eclass = ExprClass.Value;
+                       Value = v;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ec.ig.Emit (OpCodes.Ldc_R8, Value);
+               }
+
+               public override string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return this;
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return null;
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       return null;
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return null;
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return null;
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return null;
+               }
+
+               public override bool IsNegative {
+                       get {
+                               return Value < 0;
+                       }
+               }
+       }
+
+       public class DecimalConstant : Constant {
+               public readonly decimal Value;
+
+               public DecimalConstant (decimal d)
+               {
+                       type = TypeManager.decimal_type;
+                       eclass = ExprClass.Value;
+                       Value = d;
+               }
+
+               override public string AsString ()
+               {
+                       return Value.ToString ();
+               }
+
+               public override object GetValue ()
+               {
+                       return (object) Value;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       int [] words = Decimal.GetBits (Value);
+                       int power = (words [3] >> 16) & 0xff;
+
+                       if (power == 0 && Value <= int.MaxValue && Value >= int.MinValue)
+                       {
+                               IntConstant.EmitInt (ig, (int)Value);
+                               ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_int_arg);
+                               return;
+                       }
+
+                       
+                       //
+                       // FIXME: we could optimize this, and call a better 
+                       // constructor
+                       //
+
+                       IntConstant.EmitInt (ig, words [0]);
+                       IntConstant.EmitInt (ig, words [1]);
+                       IntConstant.EmitInt (ig, words [2]);
+
+                       // sign
+                       IntConstant.EmitInt (ig, words [3] >> 31);
+
+                       // power
+                       IntConstant.EmitInt (ig, power);
+
+                       ig.Emit (OpCodes.Newobj, TypeManager.void_decimal_ctor_five_args);
+               }
+
+               public override bool IsNegative {
+                       get {
+                               return Value < 0;
+                       }
+               }
+       }
+
+       public class StringConstant : Constant {
+               public readonly string Value;
+
+               public StringConstant (string s)
+               {
+                       type = TypeManager.string_type;
+                       eclass = ExprClass.Value;
+                       Value = s;
+               }
+
+               // FIXME: Escape the string.
+               override public string AsString ()
+               {
+                       return "\"" + Value + "\"";
+               }
+
+               public override object GetValue ()
+               {
+                       return Value;
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       if (Value == null)
+                               ec.ig.Emit (OpCodes.Ldnull);
+                       else
+                               ec.ig.Emit (OpCodes.Ldstr, Value);
+               }
+
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+       }
+
+}
+
+
diff --git a/mcs/bmcs/convert.cs b/mcs/bmcs/convert.cs
new file mode 100644 (file)
index 0000000..e6bdf46
--- /dev/null
@@ -0,0 +1,1998 @@
+//
+// conversion.cs: various routines for implementing conversions.
+//
+// Authors:
+//   Miguel de Icaza (miguel@ximian.com)
+//   Ravi Pratap (ravi@ximian.com)
+//
+// (C) 2001, 2002, 2003 Ximian, Inc.
+//
+
+namespace Mono.CSharp {
+       using System;
+       using System.Collections;
+       using System.Diagnostics;
+       using System.Reflection;
+       using System.Reflection.Emit;
+
+       //
+       // A container class for all the conversion operations
+       //
+       public class Convert {
+               //
+               // This is used to prettify the code: a null argument is allowed
+               // for ImplicitStandardConversion as long as it is known that
+               // no anonymous method will play a role.
+               //
+               // FIXME: renamed from `const' to `static' to allow bootstraping from older
+               // versions of the compiler that could not cope with this construct.
+               //
+               public static EmitContext ConstantEC = null;
+               
+               static public void Error_CannotConvertType (Location loc, Type source, Type target)
+               {
+                       Report.Error (30, loc, "Cannot convert type '" +
+                                     TypeManager.CSharpName (source) + "' to '" +
+                                     TypeManager.CSharpName (target) + "'");
+               }
+
+               static Expression TypeParameter_to_Null (Expression expr, Type target_type,
+                                                        Location loc)
+               {
+                       if (!TypeParameter_to_Null (target_type)) {
+                               Report.Error (403, loc, "Cannot convert null to the type " +
+                                             "parameter `{0}' becaues it could be a value " +
+                                             "type.  Consider using `default ({0})' instead.",
+                                             target_type);
+                               return null;
+                       }
+
+                       return new NullCast (expr, target_type);
+               }
+
+               static bool TypeParameter_to_Null (Type target_type)
+               {
+                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (target_type);
+                       if (gc == null)
+                               return false;
+
+                       if (gc.HasReferenceTypeConstraint)
+                               return true;
+                       if (gc.HasClassConstraint && !TypeManager.IsValueType (gc.ClassConstraint))
+                               return true;
+
+                       return false;
+               }
+
+               static Type TypeParam_EffectiveBaseType (EmitContext ec, Type t)
+               {
+                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (t);
+                       if (gc == null)
+                               return TypeManager.object_type;
+
+                       return TypeParam_EffectiveBaseType (ec, gc);
+               }
+
+               static Type TypeParam_EffectiveBaseType (EmitContext ec, GenericConstraints gc)
+               {
+                       ArrayList list = new ArrayList ();
+                       list.Add (gc.EffectiveBaseClass);
+                       foreach (Type t in gc.InterfaceConstraints) {
+                               if (!t.IsGenericParameter)
+                                       continue;
+
+                               GenericConstraints new_gc = TypeManager.GetTypeParameterConstraints (t);
+                               if (new_gc != null)
+                                       list.Add (TypeParam_EffectiveBaseType (ec, new_gc));
+                       }
+                       return FindMostEncompassedType (ec, list);
+               }
+
+               static Expression TypeParameterConversion (Expression expr, bool is_reference, Type target_type)
+               {
+                       if (is_reference)
+                               return new EmptyCast (expr, target_type);
+                       else
+                               return new BoxedCast (expr, target_type);
+               }
+
+               static Expression ImplicitTypeParameterConversion (EmitContext ec, Expression expr,
+                                                                  Type target_type)
+               {
+                       Type expr_type = expr.Type;
+
+                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (expr_type);
+
+                       if (gc == null) {
+                               if (target_type == TypeManager.object_type)
+                                       return new BoxedCast (expr);
+
+                               return null;
+                       }
+
+                       // We're converting from a type parameter which is known to be a reference type.
+                       bool is_reference = gc.IsReferenceType;
+                       Type base_type = TypeParam_EffectiveBaseType (ec, gc);
+
+                       if (TypeManager.IsSubclassOf (base_type, target_type))
+                               return TypeParameterConversion (expr, is_reference, target_type);
+
+                       if (target_type.IsInterface) {
+                               if (TypeManager.ImplementsInterface (base_type, target_type))
+                                       return TypeParameterConversion (expr, is_reference, target_type);
+
+                               foreach (Type t in gc.InterfaceConstraints) {
+                                       if (TypeManager.IsSubclassOf (t, target_type))
+                                               return TypeParameterConversion (expr, is_reference, target_type);
+                               }
+                       }
+
+                       foreach (Type t in gc.InterfaceConstraints) {
+                               if (!t.IsGenericParameter)
+                                       continue;
+                               if (TypeManager.IsSubclassOf (t, target_type))
+                                       return TypeParameterConversion (expr, is_reference, target_type);
+                       }
+
+                       return null;
+               }
+
+               static EmptyExpression MyEmptyExpr;
+               static public Expression ImplicitReferenceConversion (EmitContext ec, Expression expr, Type target_type)
+               {
+                       Type expr_type = expr.Type;
+
+                       if (expr_type == null && expr.eclass == ExprClass.MethodGroup){
+                               // if we are a method group, emit a warning
+
+                               expr.Emit (null);
+                       }
+
+                       if (expr_type == TypeManager.void_type)
+                               return null;
+
+                       if (expr_type.IsGenericParameter)
+                               return ImplicitTypeParameterConversion (ec, expr, target_type);
+                               
+                       //
+                       // notice that it is possible to write "ValueType v = 1", the ValueType here
+                       // is an abstract class, and not really a value type, so we apply the same rules.
+                       //
+                       if (target_type == TypeManager.object_type) {
+                               //
+                               // A pointer type cannot be converted to object
+                               // 
+                               if (expr_type.IsPointer)
+                                       return null;
+
+                               if (TypeManager.IsValueType (expr_type))
+                                       return new BoxedCast (expr);
+                               if (expr_type.IsClass || expr_type.IsInterface || expr_type == TypeManager.enum_type){
+                                       if (expr_type == TypeManager.anonymous_method_type)
+                                               return null;
+                                       return new EmptyCast (expr, target_type);
+                               }
+
+                               return null;
+                       } else if (target_type == TypeManager.value_type) {
+                               if (TypeManager.IsValueType (expr_type))
+                                       return new BoxedCast (expr);
+                               if (expr_type == TypeManager.null_type)
+                                       return new NullCast (expr, target_type);
+
+                               return null;
+                       } else if (TypeManager.IsSubclassOf (expr_type, target_type)) {
+                               //
+                               // Special case: enumeration to System.Enum.
+                               // System.Enum is not a value type, it is a class, so we need
+                               // a boxing conversion
+                               //
+                               if (expr_type.IsEnum || expr_type.IsGenericParameter)
+                                       return new BoxedCast (expr);
+
+                               return new EmptyCast (expr, target_type);
+                       }
+
+                       // This code is kind of mirrored inside ImplicitStandardConversionExists
+                       // with the small distinction that we only probe there
+                       //
+                       // Always ensure that the code here and there is in sync
+
+                       // from the null type to any reference-type.
+                       if (expr_type == TypeManager.null_type){
+                               if (target_type.IsPointer)
+                                       return new EmptyCast (expr, target_type);
+                                       
+                               if (!target_type.IsValueType)
+                                       return new NullCast (expr, target_type);
+                       }
+
+                       // from any class-type S to any interface-type T.
+                       if (target_type.IsInterface) {
+                               if (target_type != TypeManager.iconvertible_type &&
+                                   expr_type.IsValueType && (expr is Constant) &&
+                                   !(expr is IntLiteral || expr is BoolLiteral ||
+                                     expr is FloatLiteral || expr is DoubleLiteral ||
+                                     expr is LongLiteral || expr is CharLiteral ||
+                                     expr is StringLiteral || expr is DecimalLiteral ||
+                                     expr is UIntLiteral || expr is ULongLiteral)) {
+                                       return null;
+                               }
+
+                               if (TypeManager.ImplementsInterface (expr_type, target_type)){
+                                       if (expr_type.IsGenericParameter || TypeManager.IsValueType (expr_type))
+                                               return new BoxedCast (expr, target_type);
+                                       else
+                                               return new EmptyCast (expr, target_type);
+                               }
+                       }
+
+                       // from any interface type S to interface-type T.
+                       if (expr_type.IsInterface && target_type.IsInterface) {
+                               if (TypeManager.ImplementsInterface (expr_type, target_type))
+                                       return new EmptyCast (expr, target_type);
+                               else
+                                       return null;
+                       }
+                               
+                       // from an array-type S to an array-type of type T
+                       if (expr_type.IsArray && target_type.IsArray) {
+                               if (expr_type.GetArrayRank () == target_type.GetArrayRank ()) {
+
+                                       Type expr_element_type = TypeManager.GetElementType (expr_type);
+
+                                       if (MyEmptyExpr == null)
+                                               MyEmptyExpr = new EmptyExpression ();
+                                               
+                                       MyEmptyExpr.SetType (expr_element_type);
+                                       Type target_element_type = TypeManager.GetElementType (target_type);
+
+                                       if (!expr_element_type.IsValueType && !target_element_type.IsValueType)
+                                               if (ImplicitStandardConversionExists (ConstantEC, MyEmptyExpr,
+                                                                                     target_element_type))
+                                                       return new EmptyCast (expr, target_type);
+                               }
+                       }
+                               
+                       // from an array-type to System.Array
+                       if (expr_type.IsArray && target_type == TypeManager.array_type)
+                               return new EmptyCast (expr, target_type);
+                               
+                       // from any delegate type to System.Delegate
+                       if ((expr_type == TypeManager.delegate_type || TypeManager.IsDelegateType (expr_type)) &&
+                           target_type == TypeManager.delegate_type)
+                               return new EmptyCast (expr, target_type);
+                                       
+                       // from any array-type or delegate type into System.ICloneable.
+                       if (expr_type.IsArray ||
+                           expr_type == TypeManager.delegate_type || TypeManager.IsDelegateType (expr_type))
+                               if (target_type == TypeManager.icloneable_type)
+                                       return new EmptyCast (expr, target_type);
+
+                       // from a generic type definition to a generic instance.
+                       if (TypeManager.IsEqual (expr_type, target_type))
+                               return new EmptyCast (expr, target_type);
+
+                       return null;
+               }
+
+               //
+               // Tests whether an implicit reference conversion exists between expr_type
+               // and target_type
+               //
+               public static bool ImplicitReferenceConversionExists (EmitContext ec, Expression expr, Type target_type)
+               {
+                       Type expr_type = expr.Type;
+
+                       if (expr_type.IsGenericParameter)
+                               return ImplicitTypeParameterConversion (ec, expr, target_type) != null;
+
+                       //
+                       // This is the boxed case.
+                       //
+                       if (target_type == TypeManager.object_type) {
+                               if (expr_type.IsClass || TypeManager.IsValueType (expr_type) ||
+                                   expr_type.IsInterface || expr_type == TypeManager.enum_type)
+                                       if (target_type != TypeManager.anonymous_method_type)
+                                       return true;
+
+                               return false;
+                       } else if (TypeManager.IsSubclassOf (expr_type, target_type))
+                               return true;
+
+                       // Please remember that all code below actually comes
+                       // from ImplicitReferenceConversion so make sure code remains in sync
+                               
+                       // from any class-type S to any interface-type T.
+                       if (target_type.IsInterface) {
+                               if (target_type != TypeManager.iconvertible_type &&
+                                   expr_type.IsValueType && (expr is Constant) &&
+                                   !(expr is IntLiteral || expr is BoolLiteral ||
+                                     expr is FloatLiteral || expr is DoubleLiteral ||
+                                     expr is LongLiteral || expr is CharLiteral ||
+                                     expr is StringLiteral || expr is DecimalLiteral ||
+                                     expr is UIntLiteral || expr is ULongLiteral)) {
+                                       return false;
+                               }
+                               
+                               if (TypeManager.ImplementsInterface (expr_type, target_type))
+                                       return true;
+                       }
+                               
+                       // from any interface type S to interface-type T.
+                       if (expr_type.IsInterface && target_type.IsInterface)
+                               if (TypeManager.ImplementsInterface (expr_type, target_type))
+                                       return true;
+                               
+                       // from an array-type S to an array-type of type T
+                       if (expr_type.IsArray && target_type.IsArray) {
+                               if (expr_type.GetArrayRank () == target_type.GetArrayRank ()) {
+                                               
+                                       Type expr_element_type = expr_type.GetElementType ();
+
+                                       if (MyEmptyExpr == null)
+                                               MyEmptyExpr = new EmptyExpression ();
+                                               
+                                       MyEmptyExpr.SetType (expr_element_type);
+                                       Type target_element_type = TypeManager.GetElementType (target_type);
+                                               
+                                       if (!expr_element_type.IsValueType && !target_element_type.IsValueType)
+                                               if (ImplicitStandardConversionExists (ConstantEC, MyEmptyExpr,
+                                                                                     target_element_type))
+                                                       return true;
+                               }
+                       }
+                               
+                       // from an array-type to System.Array
+                       if (expr_type.IsArray && (target_type == TypeManager.array_type))
+                               return true;
+                               
+                       // from any delegate type to System.Delegate
+                       if ((expr_type == TypeManager.delegate_type || TypeManager.IsDelegateType (expr_type)) &&
+                           target_type == TypeManager.delegate_type)
+                               if (target_type.IsAssignableFrom (expr_type))
+                                       return true;
+                                       
+                       // from any array-type or delegate type into System.ICloneable.
+                       if (expr_type.IsArray ||
+                           expr_type == TypeManager.delegate_type || TypeManager.IsDelegateType (expr_type))
+                               if (target_type == TypeManager.icloneable_type)
+                                       return true;
+                               
+                       // from the null type to any reference-type.
+                       if (expr_type == TypeManager.null_type){
+                               if (target_type.IsPointer)
+                                       return true;
+                       
+                               if (!target_type.IsValueType)
+                                       return true;
+                       }
+
+                       // from a generic type definition to a generic instance.
+                       if (TypeManager.IsEqual (expr_type, target_type))
+                               return true;
+
+                       return false;
+               }
+
+               /// <summary>
+               ///   Implicit Numeric Conversions.
+               ///
+               ///   expr is the expression to convert, returns a new expression of type
+               ///   target_type or null if an implicit conversion is not possible.
+               /// </summary>
+               static public Expression ImplicitNumericConversion (EmitContext ec, Expression expr,
+                                                                   Type target_type, Location loc)
+               {
+                       Type expr_type = expr.Type;
+
+                       //
+                       // Attempt to do the implicit constant expression conversions
+
+                       if (expr is Constant){
+                               if (expr is IntConstant){
+                                       Expression e;
+                                       
+                                       e = TryImplicitIntConversion (target_type, (IntConstant) expr);
+                                       
+                                       if (e != null)
+                                               return e;
+                               } else if (expr is LongConstant && target_type == TypeManager.uint64_type){
+                                       //
+                                       // Try the implicit constant expression conversion
+                                       // from long to ulong, instead of a nice routine,
+                                       // we just inline it
+                                       //
+                                       long v = ((LongConstant) expr).Value;
+                                       if (v >= 0)
+                                               return new ULongConstant ((ulong) v);
+                               } 
+                       }
+                       
+                       Type real_target_type = target_type;
+
+                       if (expr_type == TypeManager.sbyte_type){
+                               //
+                               // From sbyte to short, int, long, float, double.
+                               //
+                               if (real_target_type == TypeManager.int32_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_I4);
+                               if (real_target_type == TypeManager.int64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);
+                               if (real_target_type == TypeManager.double_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);
+                               if (real_target_type == TypeManager.float_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);
+                               if (real_target_type == TypeManager.short_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_I2);
+                       } else if (expr_type == TypeManager.byte_type){
+                               //
+                               // From byte to short, ushort, int, uint, long, ulong, float, double
+                               // 
+                               if ((real_target_type == TypeManager.short_type) ||
+                                   (real_target_type == TypeManager.ushort_type) ||
+                                   (real_target_type == TypeManager.int32_type) ||
+                                   (real_target_type == TypeManager.uint32_type))
+                                       return new EmptyCast (expr, target_type);
+
+                               if (real_target_type == TypeManager.uint64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_U8);
+                               if (real_target_type == TypeManager.int64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);
+                               if (real_target_type == TypeManager.float_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);
+                               if (real_target_type == TypeManager.double_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);
+                       } else if (expr_type == TypeManager.short_type){
+                               //
+                               // From short to int, long, float, double
+                               // 
+                               if (real_target_type == TypeManager.int32_type)
+                                       return new EmptyCast (expr, target_type);
+                               if (real_target_type == TypeManager.int64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);
+                               if (real_target_type == TypeManager.double_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);
+                               if (real_target_type == TypeManager.float_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);
+                       } else if (expr_type == TypeManager.ushort_type){
+                               //
+                               // From ushort to int, uint, long, ulong, float, double
+                               //
+                               if (real_target_type == TypeManager.uint32_type)
+                                       return new EmptyCast (expr, target_type);
+
+                               if (real_target_type == TypeManager.uint64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_U8);
+                               if (real_target_type == TypeManager.int32_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_I4);
+                               if (real_target_type == TypeManager.int64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);
+                               if (real_target_type == TypeManager.double_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);
+                               if (real_target_type == TypeManager.float_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);
+                       } else if (expr_type == TypeManager.int32_type){
+                               //
+                               // From int to long, float, double
+                               //
+                               if (real_target_type == TypeManager.int64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);
+                               if (real_target_type == TypeManager.double_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);
+                               if (real_target_type == TypeManager.float_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);
+                       } else if (expr_type == TypeManager.uint32_type){
+                               //
+                               // From uint to long, ulong, float, double
+                               //
+                               if (real_target_type == TypeManager.int64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_U8);
+                               if (real_target_type == TypeManager.uint64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_U8);
+                               if (real_target_type == TypeManager.double_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R_Un,
+                                                              OpCodes.Conv_R8);
+                               if (real_target_type == TypeManager.float_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R_Un,
+                                                              OpCodes.Conv_R4);
+                       } else if (expr_type == TypeManager.int64_type){
+                               //
+                               // From long/ulong to float, double
+                               //
+                               if (real_target_type == TypeManager.double_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);
+                               if (real_target_type == TypeManager.float_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);     
+                       } else if (expr_type == TypeManager.uint64_type){
+                               //
+                               // From ulong to float, double
+                               //
+                               if (real_target_type == TypeManager.double_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R_Un,
+                                                              OpCodes.Conv_R8);
+                               if (real_target_type == TypeManager.float_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R_Un,
+                                                              OpCodes.Conv_R4);        
+                       } else if (expr_type == TypeManager.char_type){
+                               //
+                               // From char to ushort, int, uint, long, ulong, float, double
+                               // 
+                               if ((real_target_type == TypeManager.ushort_type) ||
+                                   (real_target_type == TypeManager.int32_type) ||
+                                   (real_target_type == TypeManager.uint32_type))
+                                       return new EmptyCast (expr, target_type);
+                               if (real_target_type == TypeManager.uint64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_U8);
+                               if (real_target_type == TypeManager.int64_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_I8);
+                               if (real_target_type == TypeManager.float_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R4);
+                               if (real_target_type == TypeManager.double_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);
+                       } else if (expr_type == TypeManager.float_type){
+                               //
+                               // float to double
+                               //
+                               if (real_target_type == TypeManager.double_type)
+                                       return new OpcodeCast (expr, target_type, OpCodes.Conv_R8);
+                       }
+
+                       return null;
+               }
+
+
+               /// <summary>
+               ///  Same as ImplicitStandardConversionExists except that it also looks at
+               ///  implicit user defined conversions - needed for overload resolution
+               /// </summary>
+               public static bool ImplicitConversionExists (EmitContext ec, Expression expr, Type target_type)
+               {
+                       if ((expr is NullLiteral) && target_type.IsGenericParameter)
+                               return TypeParameter_to_Null (target_type);
+
+                       if (ImplicitStandardConversionExists (ec, expr, target_type))
+                               return true;
+
+                       Expression dummy = ImplicitUserConversion (ec, expr, target_type, Location.Null);
+
+                       if (dummy != null)
+                               return true;
+
+                       return false;
+               }
+
+               public static bool ImplicitUserConversionExists (EmitContext ec, Type source, Type target)
+               {
+                       Expression dummy = ImplicitUserConversion (
+                               ec, new EmptyExpression (source), target, Location.Null);
+                       return dummy != null;
+               }
+
+               /// <summary>
+               ///  Determines if a standard implicit conversion exists from
+               ///  expr_type to target_type
+               ///
+               ///  ec should point to a real EmitContext if expr.Type is TypeManager.anonymous_method_type.
+               /// </summary>
+               public static bool ImplicitStandardConversionExists (EmitContext ec, Expression expr, Type target_type)
+               {
+                       Type expr_type = expr.Type;
+
+                       if (expr_type == TypeManager.void_type)
+                               return false;
+
+                        //Console.WriteLine ("Expr is {0}", expr);
+                        //Console.WriteLine ("{0} -> {1} ?", expr_type, target_type);
+                       if (expr_type.Equals (target_type))
+                               return true;
+
+                       // First numeric conversions 
+
+                       if (expr_type == TypeManager.sbyte_type){
+                               //
+                               // From sbyte to short, int, long, float, double.
+                               //
+                               if ((target_type == TypeManager.int32_type) || 
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type)  ||
+                                   (target_type == TypeManager.short_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                               
+                       } else if (expr_type == TypeManager.byte_type){
+                               //
+                               // From byte to short, ushort, int, uint, long, ulong, float, double
+                               // 
+                               if ((target_type == TypeManager.short_type) ||
+                                   (target_type == TypeManager.ushort_type) ||
+                                   (target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.uint32_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+       
+                       } else if (expr_type == TypeManager.short_type){
+                               //
+                               // From short to int, long, float, double
+                               // 
+                               if ((target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                       
+                       } else if (expr_type == TypeManager.ushort_type){
+                               //
+                               // From ushort to int, uint, long, ulong, float, double
+                               //
+                               if ((target_type == TypeManager.uint32_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                   
+                       } else if (expr_type == TypeManager.int32_type){
+                               //
+                               // From int to long, float, double
+                               //
+                               if ((target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                       
+                       } else if (expr_type == TypeManager.uint32_type){
+                               //
+                               // From uint to long, ulong, float, double
+                               //
+                               if ((target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                       
+                       } else if ((expr_type == TypeManager.uint64_type) ||
+                                  (expr_type == TypeManager.int64_type)) {
+                               //
+                               // From long/ulong to float, double
+                               //
+                               if ((target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                   
+                       } else if (expr_type == TypeManager.char_type){
+                               //
+                               // From char to ushort, int, uint, long, ulong, float, double
+                               // 
+                               if ((target_type == TypeManager.ushort_type) ||
+                                   (target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.uint32_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+
+                       } else if (expr_type == TypeManager.float_type){
+                               //
+                               // float to double
+                               //
+                               if (target_type == TypeManager.double_type)
+                                       return true;
+                       }       
+                       
+                       if (ImplicitReferenceConversionExists (ec, expr, target_type))
+                               return true;
+
+                       //
+                       // Implicit Constant Expression Conversions
+                       //
+                       if (expr is IntConstant){
+                               int value = ((IntConstant) expr).Value;
+
+                               if (target_type == TypeManager.sbyte_type){
+                                       if (value >= SByte.MinValue && value <= SByte.MaxValue)
+                                               return true;
+                               } else if (target_type == TypeManager.byte_type){
+                                       if (Byte.MinValue >= 0 && value <= Byte.MaxValue)
+                                               return true;
+                               } else if (target_type == TypeManager.short_type){
+                                       if (value >= Int16.MinValue && value <= Int16.MaxValue)
+                                               return true;
+                               } else if (target_type == TypeManager.ushort_type){
+                                       if (value >= UInt16.MinValue && value <= UInt16.MaxValue)
+                                               return true;
+                               } else if (target_type == TypeManager.uint32_type){
+                                       if (value >= 0)
+                                               return true;
+                               } else if (target_type == TypeManager.uint64_type){
+                                        //
+                                        // we can optimize this case: a positive int32
+                                        // always fits on a uint64.  But we need an opcode
+                                        // to do it.
+                                        //
+                                       if (value >= 0)
+                                               return true;
+                               }
+                               
+                               if (value == 0 && expr is IntLiteral && TypeManager.IsEnumType (target_type))
+                                       return true;
+                       }
+
+                       if (expr is LongConstant && target_type == TypeManager.uint64_type){
+                               //
+                               // Try the implicit constant expression conversion
+                               // from long to ulong, instead of a nice routine,
+                               // we just inline it
+                               //
+                               long v = ((LongConstant) expr).Value;
+                               if (v > 0)
+                                       return true;
+                       }
+                       
+                       if ((target_type == TypeManager.enum_type ||
+                            target_type.IsSubclassOf (TypeManager.enum_type)) &&
+                            expr is IntLiteral){
+                               IntLiteral i = (IntLiteral) expr;
+
+                               if (i.Value == 0)
+                                       return true;
+                       }
+
+                       if (target_type == TypeManager.void_ptr_type && expr_type.IsPointer)
+                               return true;
+
+                       if (expr_type == TypeManager.anonymous_method_type){
+                               if (!TypeManager.IsDelegateType (target_type))
+                                       return false;
+
+                               AnonymousMethod am = (AnonymousMethod) expr;
+                               int errors = Report.Errors;
+
+                               Expression conv = am.Compatible (ec, target_type, true);
+                               if (conv != null)
+                                       return true;
+                       }
+                       
+                       return false;
+               }
+
+               //
+               // Used internally by FindMostEncompassedType, this is used
+               // to avoid creating lots of objects in the tight loop inside
+               // FindMostEncompassedType
+               //
+               static EmptyExpression priv_fmet_param;
+               
+               /// <summary>
+               ///  Finds "most encompassed type" according to the spec (13.4.2)
+               ///  amongst the methods in the MethodGroupExpr
+               /// </summary>
+               static Type FindMostEncompassedType (EmitContext ec, ArrayList types)
+               {
+                       Type best = null;
+
+                       if (priv_fmet_param == null)
+                               priv_fmet_param = new EmptyExpression ();
+
+                       foreach (Type t in types){
+                               priv_fmet_param.SetType (t);
+                               
+                               if (best == null) {
+                                       best = t;
+                                       continue;
+                               }
+                               
+                               if (ImplicitStandardConversionExists (ec, priv_fmet_param, best))
+                                       best = t;
+                       }
+
+                       return best;
+               }
+
+               //
+               // Used internally by FindMostEncompassingType, this is used
+               // to avoid creating lots of objects in the tight loop inside
+               // FindMostEncompassingType
+               //
+               static EmptyExpression priv_fmee_ret;
+               
+               /// <summary>
+               ///  Finds "most encompassing type" according to the spec (13.4.2)
+               ///  amongst the types in the given set
+               /// </summary>
+               static Type FindMostEncompassingType (EmitContext ec, ArrayList types)
+               {
+                       Type best = null;
+
+                       if (priv_fmee_ret == null)
+                               priv_fmee_ret = new EmptyExpression ();
+
+                       foreach (Type t in types){
+                               priv_fmee_ret.SetType (best);
+
+                               if (best == null) {
+                                       best = t;
+                                       continue;
+                               }
+
+                               if (ImplicitStandardConversionExists (ec, priv_fmee_ret, t))
+                                       best = t;
+                       }
+                       
+                       return best;
+               }
+
+               //
+               // Used to avoid creating too many objects
+               //
+               static EmptyExpression priv_fms_expr;
+               
+               /// <summary>
+               ///   Finds the most specific source Sx according to the rules of the spec (13.4.4)
+               ///   by making use of FindMostEncomp* methods. Applies the correct rules separately
+               ///   for explicit and implicit conversion operators.
+               /// </summary>
+               static public Type FindMostSpecificSource (EmitContext ec, MethodGroupExpr me,
+                                                          Expression source, bool apply_explicit_conv_rules,
+                                                          Location loc)
+               {
+                       ArrayList src_types_set = new ArrayList ();
+                       
+                       if (priv_fms_expr == null)
+                               priv_fms_expr = new EmptyExpression ();
+
+                       //
+                       // If any operator converts from S then Sx = S
+                       //
+                       Type source_type = source.Type;
+                       foreach (MethodBase mb in me.Methods){
+                               ParameterData pd = Invocation.GetParameterData (mb);
+                               Type param_type = pd.ParameterType (0);
+
+                               if (param_type == source_type)
+                                       return param_type;
+
+                               if (apply_explicit_conv_rules) {
+                                       //
+                                       // From the spec :
+                                       // Find the set of applicable user-defined conversion operators, U.  This set
+                                       // consists of the
+                                       // user-defined implicit or explicit conversion operators declared by
+                                       // the classes or structs in D that convert from a type encompassing
+                                       // or encompassed by S to a type encompassing or encompassed by T
+                                       //
+                                       priv_fms_expr.SetType (param_type);
+                                       if (ImplicitStandardConversionExists (ec, priv_fms_expr, source_type))
+                                               src_types_set.Add (param_type);
+                                       else {
+                                               if (ImplicitStandardConversionExists (ec, source, param_type))
+                                                       src_types_set.Add (param_type);
+                                       }
+                               } else {
+                                       //
+                                       // Only if S is encompassed by param_type
+                                       //
+                                       if (ImplicitStandardConversionExists (ec, source, param_type))
+                                               src_types_set.Add (param_type);
+                               }
+                       }
+                       
+                       //
+                       // Explicit Conv rules
+                       //
+                       if (apply_explicit_conv_rules) {
+                               ArrayList candidate_set = new ArrayList ();
+
+                               foreach (Type param_type in src_types_set){
+                                       if (ImplicitStandardConversionExists (ec, source, param_type))
+                                               candidate_set.Add (param_type);
+                               }
+
+                               if (candidate_set.Count != 0)
+                                       return FindMostEncompassedType (ec, candidate_set);
+                       }
+
+                       //
+                       // Final case
+                       //
+                       if (apply_explicit_conv_rules)
+                               return FindMostEncompassingType (ec, src_types_set);
+                       else
+                               return FindMostEncompassedType (ec, src_types_set);
+               }
+
+               //
+               // Useful in avoiding proliferation of objects
+               //
+               static EmptyExpression priv_fmt_expr;
+               
+               /// <summary>
+               ///  Finds the most specific target Tx according to section 13.4.4
+               /// </summary>
+               static public Type FindMostSpecificTarget (EmitContext ec, MethodGroupExpr me,
+                                                          Type target, bool apply_explicit_conv_rules,
+                                                          Location loc)
+               {
+                       ArrayList tgt_types_set = new ArrayList ();
+                       
+                       if (priv_fmt_expr == null)
+                               priv_fmt_expr = new EmptyExpression ();
+                       
+                       //
+                       // If any operator converts to T then Tx = T
+                       //
+                       foreach (MethodInfo mi in me.Methods){
+                               Type ret_type = mi.ReturnType;
+
+                               if (ret_type == target)
+                                       return ret_type;
+
+                               if (apply_explicit_conv_rules) {
+                                       //
+                                       // From the spec :
+                                       // Find the set of applicable user-defined conversion operators, U.
+                                       //
+                                       // This set consists of the
+                                       // user-defined implicit or explicit conversion operators declared by
+                                       // the classes or structs in D that convert from a type encompassing
+                                       // or encompassed by S to a type encompassing or encompassed by T
+                                       //
+                                       priv_fms_expr.SetType (ret_type);
+                                       if (ImplicitStandardConversionExists (ec, priv_fms_expr, target))
+                                               tgt_types_set.Add (ret_type);
+                                       else {
+                                               priv_fms_expr.SetType (target);
+                                               if (ImplicitStandardConversionExists (ec, priv_fms_expr, ret_type))
+                                                       tgt_types_set.Add (ret_type);
+                                       }
+                               } else {
+                                       //
+                                       // Only if T is encompassed by param_type
+                                       //
+                                       priv_fms_expr.SetType (ret_type);
+                                       if (ImplicitStandardConversionExists (ec, priv_fms_expr, target))
+                                               tgt_types_set.Add (ret_type);
+                               }
+                       }
+
+                       //
+                       // Explicit conv rules
+                       //
+                       if (apply_explicit_conv_rules) {
+                               ArrayList candidate_set = new ArrayList ();
+
+                               foreach (Type ret_type in tgt_types_set){
+                                       priv_fmt_expr.SetType (ret_type);
+                                       
+                                       if (ImplicitStandardConversionExists (ec, priv_fmt_expr, target))
+                                               candidate_set.Add (ret_type);
+                               }
+
+                               if (candidate_set.Count != 0)
+                                       return FindMostEncompassingType (ec, candidate_set);
+                       }
+                       
+                       //
+                       // Okay, final case !
+                       //
+                       if (apply_explicit_conv_rules)
+                               return FindMostEncompassedType (ec, tgt_types_set);
+                       else 
+                               return FindMostEncompassingType (ec, tgt_types_set);
+               }
+               
+               /// <summary>
+               ///  User-defined Implicit conversions
+               /// </summary>
+               static public Expression ImplicitUserConversion (EmitContext ec, Expression source,
+                                                                Type target, Location loc)
+               {
+                       return UserDefinedConversion (ec, source, target, loc, false);
+               }
+
+               /// <summary>
+               ///  User-defined Explicit conversions
+               /// </summary>
+               static public Expression ExplicitUserConversion (EmitContext ec, Expression source,
+                                                                Type target, Location loc)
+               {
+                       return UserDefinedConversion (ec, source, target, loc, true);
+               }
+
+               static DoubleHash explicit_conv = new DoubleHash (100);
+               static DoubleHash implicit_conv = new DoubleHash (100);
+               /// <summary>
+               ///   Computes the MethodGroup for the user-defined conversion
+               ///   operators from source_type to target_type.  `look_for_explicit'
+               ///   controls whether we should also include the list of explicit
+               ///   operators
+               /// </summary>
+               static MethodGroupExpr GetConversionOperators (EmitContext ec,
+                                                              Type source_type, Type target_type,
+                                                              Location loc, bool look_for_explicit)
+               {
+                       Expression mg1 = null, mg2 = null;
+                       Expression mg5 = null, mg6 = null, mg7 = null, mg8 = null;
+                       string op_name;
+
+                       op_name = "op_Implicit";
+
+                       MethodGroupExpr union3;
+                       object r;
+                       if ((look_for_explicit ? explicit_conv : implicit_conv).Lookup (source_type, target_type, out r))
+                               return (MethodGroupExpr) r;
+
+                       mg1 = Expression.MethodLookup (ec, source_type, op_name, loc);
+                       if (source_type.BaseType != null)
+                               mg2 = Expression.MethodLookup (ec, source_type.BaseType, op_name, loc);
+
+                       if (mg1 == null)
+                               union3 = (MethodGroupExpr) mg2;
+                       else if (mg2 == null)
+                               union3 = (MethodGroupExpr) mg1;
+                       else
+                               union3 = Invocation.MakeUnionSet (mg1, mg2, loc);
+
+                       mg1 = Expression.MethodLookup (ec, target_type, op_name, loc);
+                       if (mg1 != null){
+                               if (union3 != null)
+                                       union3 = Invocation.MakeUnionSet (union3, mg1, loc);
+                               else
+                                       union3 = (MethodGroupExpr) mg1;
+                       }
+
+                       if (target_type.BaseType != null)
+                               mg1 = Expression.MethodLookup (ec, target_type.BaseType, op_name, loc);
+                       
+                       if (mg1 != null){
+                               if (union3 != null)
+                                       union3 = Invocation.MakeUnionSet (union3, mg1, loc);
+                               else
+                                       union3 = (MethodGroupExpr) mg1;
+                       }
+
+                       MethodGroupExpr union4 = null;
+
+                       if (look_for_explicit) {
+                               op_name = "op_Explicit";
+
+                               mg5 = Expression.MemberLookup (ec, source_type, op_name, loc);
+                               if (source_type.BaseType != null)
+                                       mg6 = Expression.MethodLookup (ec, source_type.BaseType, op_name, loc);
+                               
+                               mg7 = Expression.MemberLookup (ec, target_type, op_name, loc);
+                               if (target_type.BaseType != null)
+                                       mg8 = Expression.MethodLookup (ec, target_type.BaseType, op_name, loc);
+                               
+                               MethodGroupExpr union5 = Invocation.MakeUnionSet (mg5, mg6, loc);
+                               MethodGroupExpr union6 = Invocation.MakeUnionSet (mg7, mg8, loc);
+
+                               union4 = Invocation.MakeUnionSet (union5, union6, loc);
+                       }
+                       
+                       MethodGroupExpr ret = Invocation.MakeUnionSet (union3, union4, loc);
+                       (look_for_explicit ? explicit_conv : implicit_conv).Insert (source_type, target_type, ret);
+                       return ret;
+               }
+               
+               /// <summary>
+               ///   User-defined conversions
+               /// </summary>
+               static public Expression UserDefinedConversion (EmitContext ec, Expression source,
+                                                               Type target, Location loc,
+                                                               bool look_for_explicit)
+               {
+                       MethodGroupExpr union;
+                       Type source_type = source.Type;
+                       MethodBase method = null;
+
+                       union = GetConversionOperators (ec, source_type, target, loc, look_for_explicit);
+                       if (union == null)
+                               return null;
+                       
+                       Type most_specific_source, most_specific_target;
+
+                       most_specific_source = FindMostSpecificSource (ec, union, source, look_for_explicit, loc);
+                       if (most_specific_source == null)
+                               return null;
+
+                       most_specific_target = FindMostSpecificTarget (ec, union, target, look_for_explicit, loc);
+                       if (most_specific_target == null) 
+                               return null;
+
+                       int count = 0;
+
+                       
+                       foreach (MethodBase mb in union.Methods){
+                               ParameterData pd = Invocation.GetParameterData (mb);
+                               MethodInfo mi = (MethodInfo) mb;
+                               
+                               if (pd.ParameterType (0) == most_specific_source &&
+                                   mi.ReturnType == most_specific_target) {
+                                       method = mb;
+                                       count++;
+                               }
+                       }
+                       
+                       if (method == null || count > 1)
+                               return null;
+                       
+                       
+                       //
+                       // This will do the conversion to the best match that we
+                       // found.  Now we need to perform an implict standard conversion
+                       // if the best match was not the type that we were requested
+                       // by target.
+                       //
+                       if (look_for_explicit)
+                               source = ExplicitConversionStandard (ec, source, most_specific_source, loc);
+                       else
+                               source = ImplicitConversionStandard (ec, source, most_specific_source, loc);
+
+                       if (source == null)
+                               return null;
+
+                       Expression e;
+                       e =  new UserCast ((MethodInfo) method, source, loc);
+                       if (e.Type != target){
+                               if (!look_for_explicit)
+                                       e = ImplicitConversionStandard (ec, e, target, loc);
+                               else
+                                       e = ExplicitConversionStandard (ec, e, target, loc);
+                       }
+
+                       return e;
+               }
+               
+               /// <summary>
+               ///   Converts implicitly the resolved expression `expr' into the
+               ///   `target_type'.  It returns a new expression that can be used
+               ///   in a context that expects a `target_type'. 
+               /// </summary>
+               static public Expression ImplicitConversion (EmitContext ec, Expression expr,
+                                                            Type target_type, Location loc)
+               {
+                       Expression e;
+
+                       if (target_type == null)
+                               throw new Exception ("Target type is null");
+
+                       e = ImplicitConversionStandard (ec, expr, target_type, loc);
+                       if (e != null)
+                               return e;
+
+                       e = ImplicitUserConversion (ec, expr, target_type, loc);
+                       if (e != null)
+                               return e;
+
+                       return null;
+               }
+
+               
+               /// <summary>
+               ///   Attempts to apply the `Standard Implicit
+               ///   Conversion' rules to the expression `expr' into
+               ///   the `target_type'.  It returns a new expression
+               ///   that can be used in a context that expects a
+               ///   `target_type'.
+               ///
+               ///   This is different from `ImplicitConversion' in that the
+               ///   user defined implicit conversions are excluded. 
+               /// </summary>
+               static public Expression ImplicitConversionStandard (EmitContext ec, Expression expr,
+                                                                    Type target_type, Location loc)
+               {
+                       Type expr_type = expr.Type;
+                       Expression e;
+
+                       if ((expr is NullLiteral) && target_type.IsGenericParameter)
+                               return TypeParameter_to_Null (expr, target_type, loc);
+
+                       if (expr.eclass == ExprClass.MethodGroup){
+                               if (!TypeManager.IsDelegateType (target_type)){
+                                       return null;
+                               }
+
+                               //
+                               // Only allow anonymous method conversions on post ISO_1
+                               //
+                               if (RootContext.Version != LanguageVersion.ISO_1){
+                                       MethodGroupExpr mg = expr as MethodGroupExpr;
+                                       if (mg != null)
+                                               return ImplicitDelegateCreation.Create (ec, mg, target_type, loc);
+                               }
+                       }
+
+                       if (expr_type.Equals (target_type) && !TypeManager.IsNullType (expr_type))
+                               return expr;
+
+                       e = ImplicitNumericConversion (ec, expr, target_type, loc);
+                       if (e != null)
+                               return e;
+
+                       e = ImplicitReferenceConversion (ec, expr, target_type);
+                       if (e != null)
+                               return e;
+                       
+                       if ((target_type == TypeManager.enum_type ||
+                            target_type.IsSubclassOf (TypeManager.enum_type)) &&
+                           expr is IntLiteral){
+                               IntLiteral i = (IntLiteral) expr;
+
+                               if (i.Value == 0)
+                                       return new EnumConstant ((Constant) expr, target_type);
+                       }
+
+                       if (ec.InUnsafe) {
+                               if (expr_type.IsPointer){
+                                       if (target_type == TypeManager.void_ptr_type)
+                                               return new EmptyCast (expr, target_type);
+
+                                       //
+                                       // yep, comparing pointer types cant be done with
+                                       // t1 == t2, we have to compare their element types.
+                                       //
+                                       if (target_type.IsPointer){
+                                               if (TypeManager.GetElementType(target_type) == TypeManager.GetElementType(expr_type))
+                                                       return expr;
+                                       }
+                               }
+                               
+                               if (target_type.IsPointer) {
+                                       if (expr_type == TypeManager.null_type)
+                                               return new EmptyCast (expr, target_type);
+
+                                       if (expr_type == TypeManager.void_ptr_type)
+                                               return new EmptyCast (expr, target_type);
+                               }
+                       }
+
+                       if (expr_type == TypeManager.anonymous_method_type){
+                               if (!TypeManager.IsDelegateType (target_type)){
+                                       Report.Error (1660, loc,
+                                                             "Cannot convert anonymous method to `{0}', since it is not a delegate",
+                                                             TypeManager.CSharpName (target_type));
+                                       return null;
+                               }
+
+                               AnonymousMethod am = (AnonymousMethod) expr;
+                               int errors = Report.Errors;
+
+                               Expression conv = am.Compatible (ec, target_type, false);
+                               if (conv != null)
+                                       return conv;
+                               
+                               //
+                               // We return something instead of null, to avoid
+                               // the duplicate error, since am.Compatible would have
+                               // reported that already
+                               //
+                               if (errors != Report.Errors)
+                                       return new EmptyCast (expr, target_type);
+                       }
+                       
+                       return null;
+               }
+
+               /// <summary>
+               ///   Attemps to perform an implict constant conversion of the IntConstant
+               ///   into a different data type using casts (See Implicit Constant
+               ///   Expression Conversions)
+               /// </summary>
+               static public Expression TryImplicitIntConversion (Type target_type, IntConstant ic)
+               {
+                       int value = ic.Value;
+
+                       if (target_type == TypeManager.sbyte_type){
+                               if (value >= SByte.MinValue && value <= SByte.MaxValue)
+                                       return new SByteConstant ((sbyte) value);
+                       } else if (target_type == TypeManager.byte_type){
+                               if (value >= Byte.MinValue && value <= Byte.MaxValue)
+                                       return new ByteConstant ((byte) value);
+                       } else if (target_type == TypeManager.short_type){
+                               if (value >= Int16.MinValue && value <= Int16.MaxValue)
+                                       return new ShortConstant ((short) value);
+                       } else if (target_type == TypeManager.ushort_type){
+                               if (value >= UInt16.MinValue && value <= UInt16.MaxValue)
+                                       return new UShortConstant ((ushort) value);
+                       } else if (target_type == TypeManager.uint32_type){
+                               if (value >= 0)
+                                       return new UIntConstant ((uint) value);
+                       } else if (target_type == TypeManager.uint64_type){
+                               //
+                               // we can optimize this case: a positive int32
+                               // always fits on a uint64.  But we need an opcode
+                               // to do it.
+                               //
+                               if (value >= 0)
+                                       return new ULongConstant ((ulong) value);
+                       } else if (target_type == TypeManager.double_type)
+                               return new DoubleConstant ((double) value);
+                       else if (target_type == TypeManager.float_type)
+                               return new FloatConstant ((float) value);
+                       
+                       if (value == 0 && ic is IntLiteral && TypeManager.IsEnumType (target_type)){
+                               Type underlying = TypeManager.EnumToUnderlying (target_type);
+                               Constant e = (Constant) ic;
+                               
+                               //
+                               // Possibly, we need to create a different 0 literal before passing
+                               // to EnumConstant
+                               //
+                               if (underlying == TypeManager.int64_type)
+                                       e = new LongLiteral (0);
+                               else if (underlying == TypeManager.uint64_type)
+                                       e = new ULongLiteral (0);
+
+                               return new EnumConstant (e, target_type);
+                       }
+                       return null;
+               }
+
+               static public void Error_CannotImplicitConversion (Location loc, Type source, Type target)
+               {
+                       if (source.Name == target.Name){
+                               Report.ExtraInformation (loc,
+                                        String.Format (
+                                               "The type {0} has two conflicting definitons, one comes from {0} and the other from {1}",
+                                               source.Assembly.FullName, target.Assembly.FullName));
+                                                        
+                       }
+                       Report.Error (29, loc, "Cannot convert implicitly from {0} to `{1}'",
+                                     source == TypeManager.anonymous_method_type ?
+                                     "anonymous method" : "`" + TypeManager.CSharpName (source) + "'",
+                                     TypeManager.CSharpName (target));
+               }
+
+               /// <summary>
+               ///   Attemptes to implicityly convert `target' into `type', using
+               ///   ImplicitConversion.  If there is no implicit conversion, then
+               ///   an error is signaled
+               /// </summary>
+               static public Expression ImplicitConversionRequired (EmitContext ec, Expression source,
+                                                                    Type target_type, Location loc)
+               {
+                       Expression e;
+
+                       int errors = Report.Errors;
+                       e = ImplicitConversion (ec, source, target_type, loc);
+                       if (Report.Errors > errors)
+                               return null;
+                       if (e != null)
+                               return e;
+
+                       if (source is DoubleLiteral) {
+                               if (target_type == TypeManager.float_type) {
+                                       Error_664 (loc, "float", "f");
+                                       return null;
+                               }
+                               if (target_type == TypeManager.decimal_type) {
+                                       Error_664 (loc, "decimal", "m");
+                                       return null;
+                               }
+                       }
+
+                       if (source is Constant){
+                               Constant c = (Constant) source;
+
+                               Expression.Error_ConstantValueCannotBeConverted (loc, c.AsString (), target_type);
+                               return null;
+                       }
+                       
+                       Error_CannotImplicitConversion (loc, source.Type, target_type);
+
+                       return null;
+               }
+
+               static void Error_664 (Location loc, string type, string suffix) {
+                       Report.Error (664, loc,
+                               "Literal of type double cannot be implicitly converted to type '{0}'. Add suffix '{1}' to create a literal of this type",
+                               type, suffix);
+               }
+
+               /// <summary>
+               ///   Performs the explicit numeric conversions
+               /// </summary>
+               static Expression ExplicitNumericConversion (EmitContext ec, Expression expr, Type target_type, Location loc)
+               {
+                       Type expr_type = expr.Type;
+
+                       //
+                       // If we have an enumeration, extract the underlying type,
+                       // use this during the comparison, but wrap around the original
+                       // target_type
+                       //
+                       Type real_target_type = target_type;
+
+                       if (TypeManager.IsEnumType (real_target_type))
+                               real_target_type = TypeManager.EnumToUnderlying (real_target_type);
+
+                       if (ImplicitStandardConversionExists (ec, expr, real_target_type)){
+                               Expression ce = ImplicitConversionStandard (ec, expr, real_target_type, loc);
+
+                               if (real_target_type != target_type)
+                                       return new EmptyCast (ce, target_type);
+                               return ce;
+                       }
+                       
+                       if (expr_type == TypeManager.sbyte_type){
+                               //
+                               // From sbyte to byte, ushort, uint, ulong, char
+                               //
+                               if (real_target_type == TypeManager.byte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_U1);
+                               if (real_target_type == TypeManager.ushort_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_U2);
+                               if (real_target_type == TypeManager.uint32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_U4);
+                               if (real_target_type == TypeManager.uint64_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_U8);
+                               if (real_target_type == TypeManager.char_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I1_CH);
+                       } else if (expr_type == TypeManager.byte_type){
+                               //
+                               // From byte to sbyte and char
+                               //
+                               if (real_target_type == TypeManager.sbyte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U1_I1);
+                               if (real_target_type == TypeManager.char_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U1_CH);
+                       } else if (expr_type == TypeManager.short_type){
+                               //
+                               // From short to sbyte, byte, ushort, uint, ulong, char
+                               //
+                               if (real_target_type == TypeManager.sbyte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_I1);
+                               if (real_target_type == TypeManager.byte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_U1);
+                               if (real_target_type == TypeManager.ushort_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_U2);
+                               if (real_target_type == TypeManager.uint32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_U4);
+                               if (real_target_type == TypeManager.uint64_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_U8);
+                               if (real_target_type == TypeManager.char_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I2_CH);
+                       } else if (expr_type == TypeManager.ushort_type){
+                               //
+                               // From ushort to sbyte, byte, short, char
+                               //
+                               if (real_target_type == TypeManager.sbyte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_I1);
+                               if (real_target_type == TypeManager.byte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_U1);
+                               if (real_target_type == TypeManager.short_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_I2);
+                               if (real_target_type == TypeManager.char_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U2_CH);
+                       } else if (expr_type == TypeManager.int32_type){
+                               //
+                               // From int to sbyte, byte, short, ushort, uint, ulong, char
+                               //
+                               if (real_target_type == TypeManager.sbyte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_I1);
+                               if (real_target_type == TypeManager.byte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_U1);
+                               if (real_target_type == TypeManager.short_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_I2);
+                               if (real_target_type == TypeManager.ushort_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_U2);
+                               if (real_target_type == TypeManager.uint32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_U4);
+                               if (real_target_type == TypeManager.uint64_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_U8);
+                               if (real_target_type == TypeManager.char_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I4_CH);
+                       } else if (expr_type == TypeManager.uint32_type){
+                               //
+                               // From uint to sbyte, byte, short, ushort, int, char
+                               //
+                               if (real_target_type == TypeManager.sbyte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_I1);
+                               if (real_target_type == TypeManager.byte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_U1);
+                               if (real_target_type == TypeManager.short_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_I2);
+                               if (real_target_type == TypeManager.ushort_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_U2);
+                               if (real_target_type == TypeManager.int32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_I4);
+                               if (real_target_type == TypeManager.char_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U4_CH);
+                       } else if (expr_type == TypeManager.int64_type){
+                               //
+                               // From long to sbyte, byte, short, ushort, int, uint, ulong, char
+                               //
+                               if (real_target_type == TypeManager.sbyte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_I1);
+                               if (real_target_type == TypeManager.byte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_U1);
+                               if (real_target_type == TypeManager.short_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_I2);
+                               if (real_target_type == TypeManager.ushort_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_U2);
+                               if (real_target_type == TypeManager.int32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_I4);
+                               if (real_target_type == TypeManager.uint32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_U4);
+                               if (real_target_type == TypeManager.uint64_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_U8);
+                               if (real_target_type == TypeManager.char_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.I8_CH);
+                       } else if (expr_type == TypeManager.uint64_type){
+                               //
+                               // From ulong to sbyte, byte, short, ushort, int, uint, long, char
+                               //
+                               if (real_target_type == TypeManager.sbyte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_I1);
+                               if (real_target_type == TypeManager.byte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_U1);
+                               if (real_target_type == TypeManager.short_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_I2);
+                               if (real_target_type == TypeManager.ushort_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_U2);
+                               if (real_target_type == TypeManager.int32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_I4);
+                               if (real_target_type == TypeManager.uint32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_U4);
+                               if (real_target_type == TypeManager.int64_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_I8);
+                               if (real_target_type == TypeManager.char_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.U8_CH);
+                       } else if (expr_type == TypeManager.char_type){
+                               //
+                               // From char to sbyte, byte, short
+                               //
+                               if (real_target_type == TypeManager.sbyte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.CH_I1);
+                               if (real_target_type == TypeManager.byte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.CH_U1);
+                               if (real_target_type == TypeManager.short_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.CH_I2);
+                       } else if (expr_type == TypeManager.float_type){
+                               //
+                               // From float to sbyte, byte, short,
+                               // ushort, int, uint, long, ulong, char
+                               // or decimal
+                               //
+                               if (real_target_type == TypeManager.sbyte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R4_I1);
+                               if (real_target_type == TypeManager.byte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R4_U1);
+                               if (real_target_type == TypeManager.short_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R4_I2);
+                               if (real_target_type == TypeManager.ushort_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R4_U2);
+                               if (real_target_type == TypeManager.int32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R4_I4);
+                               if (real_target_type == TypeManager.uint32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R4_U4);
+                               if (real_target_type == TypeManager.int64_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R4_I8);
+                               if (real_target_type == TypeManager.uint64_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R4_U8);
+                               if (real_target_type == TypeManager.char_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R4_CH);
+                       } else if (expr_type == TypeManager.double_type){
+                               //
+                               // From double to byte, byte, short,
+                               // ushort, int, uint, long, ulong,
+                               // char, float or decimal
+                               //
+                               if (real_target_type == TypeManager.sbyte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_I1);
+                               if (real_target_type == TypeManager.byte_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_U1);
+                               if (real_target_type == TypeManager.short_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_I2);
+                               if (real_target_type == TypeManager.ushort_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_U2);
+                               if (real_target_type == TypeManager.int32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_I4);
+                               if (real_target_type == TypeManager.uint32_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_U4);
+                               if (real_target_type == TypeManager.int64_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_I8);
+                               if (real_target_type == TypeManager.uint64_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_U8);
+                               if (real_target_type == TypeManager.char_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_CH);
+                               if (real_target_type == TypeManager.float_type)
+                                       return new ConvCast (ec, expr, target_type, ConvCast.Mode.R8_R4);
+                       } 
+
+                       // decimal is taken care of by the op_Explicit methods.
+
+                       return null;
+               }
+
+               /// <summary>
+               ///  Returns whether an explicit reference conversion can be performed
+               ///  from source_type to target_type
+               /// </summary>
+               public static bool ExplicitReferenceConversionExists (Type source_type, Type target_type)
+               {
+                       bool target_is_type_param = target_type.IsGenericParameter;
+                       bool target_is_value_type = target_type.IsValueType;
+                       
+                       if (source_type == target_type)
+                               return true;
+
+                       //
+                       // From object to a generic parameter
+                       //
+                       if (source_type == TypeManager.object_type && target_is_type_param)
+                               return true;
+
+                       //
+                       // From object to any reference type
+                       //
+                       if (source_type == TypeManager.object_type && !target_is_value_type)
+                               return true;
+                                       
+                       //
+                       // From any class S to any class-type T, provided S is a base class of T
+                       //
+                       if (TypeManager.IsSubclassOf (target_type, source_type))
+                               return true;
+
+                       //
+                       // From any interface type S to any interface T provided S is not derived from T
+                       //
+                       if (source_type.IsInterface && target_type.IsInterface){
+                               if (!TypeManager.IsSubclassOf (target_type, source_type))
+                                       return true;
+                       }
+                           
+                       //
+                       // From any class type S to any interface T, provided S is not sealed
+                       // and provided S does not implement T.
+                       //
+                       if (target_type.IsInterface && !source_type.IsSealed &&
+                           !TypeManager.ImplementsInterface (source_type, target_type))
+                               return true;
+
+                       //
+                       // From any interface-type S to to any class type T, provided T is not
+                       // sealed, or provided T implements S.
+                       //
+                       if (source_type.IsInterface &&
+                           (!target_type.IsSealed || TypeManager.ImplementsInterface (target_type, source_type)))
+                               return true;
+                       
+                       
+                       // From an array type S with an element type Se to an array type T with an 
+                       // element type Te provided all the following are true:
+                       //     * S and T differe only in element type, in other words, S and T
+                       //       have the same number of dimensions.
+                       //     * Both Se and Te are reference types
+                       //     * An explicit referenc conversions exist from Se to Te
+                       //
+                       if (source_type.IsArray && target_type.IsArray) {
+                               if (source_type.GetArrayRank () == target_type.GetArrayRank ()) {
+                                       
+                                       Type source_element_type = TypeManager.GetElementType (source_type);
+                                       Type target_element_type = TypeManager.GetElementType (target_type);
+                                       
+                                       if (!source_element_type.IsValueType && !target_element_type.IsValueType)
+                                               if (ExplicitReferenceConversionExists (source_element_type,
+                                                                                      target_element_type))
+                                                       return true;
+                               }
+                       }
+                       
+
+                       // From System.Array to any array-type
+                       if (source_type == TypeManager.array_type &&
+                           target_type.IsArray){
+                               return true;
+                       }
+
+                       //
+                       // From System delegate to any delegate-type
+                       //
+                       if (source_type == TypeManager.delegate_type &&
+                           TypeManager.IsDelegateType (target_type))
+                               return true;
+
+                       //
+                       // From ICloneable to Array or Delegate types
+                       //
+                       if (source_type == TypeManager.icloneable_type &&
+                           (target_type == TypeManager.array_type ||
+                            target_type == TypeManager.delegate_type))
+                               return true;
+                       
+                       return false;
+               }
+
+               /// <summary>
+               ///   Implements Explicit Reference conversions
+               /// </summary>
+               static Expression ExplicitReferenceConversion (Expression source, Type target_type)
+               {
+                       Type source_type = source.Type;
+                       bool target_is_type_param = target_type.IsGenericParameter;
+                       bool target_is_value_type = target_type.IsValueType;
+
+                       //
+                       // From object to a generic parameter
+                       //
+                       if (source_type == TypeManager.object_type && target_is_type_param)
+                               return new UnboxCast (source, target_type);
+
+                       //
+                       // From object to any reference type
+                       //
+                       if (source_type == TypeManager.object_type && !target_is_value_type)
+                               return new ClassCast (source, target_type);
+
+                       //
+                       // Unboxing conversion.
+                       //
+                       if (((source_type == TypeManager.enum_type &&
+                               !(source is EmptyCast)) ||
+                               source_type == TypeManager.value_type) && target_is_value_type)
+                               return new UnboxCast (source, target_type);
+
+                       //
+                       // From any class S to any class-type T, provided S is a base class of T
+                       //
+                       if (TypeManager.IsSubclassOf (target_type, source_type))
+                               return new ClassCast (source, target_type);
+
+                       //
+                       // From any interface type S to any interface T provided S is not derived from T
+                       //
+                       if (source_type.IsInterface && target_type.IsInterface){
+                               if (TypeManager.ImplementsInterface (source_type, target_type))
+                                       return null;
+                               else
+                                       return new ClassCast (source, target_type);
+                       }
+
+                       //
+                       // From any class type S to any interface T, provides S is not sealed
+                       // and provided S does not implement T.
+                       //
+                       if (target_type.IsInterface && !source_type.IsSealed) {
+                               if (TypeManager.ImplementsInterface (source_type, target_type))
+                                       return null;
+                               else
+                                       return new ClassCast (source, target_type);
+                               
+                       }
+
+                       //
+                       // From any interface-type S to to any class type T, provided T is not
+                       // sealed, or provided T implements S.
+                       //
+                       if (source_type.IsInterface) {
+                               if (!target_type.IsSealed || TypeManager.ImplementsInterface (target_type, source_type)) {
+                                       if (target_type.IsClass)
+                                               return new ClassCast (source, target_type);
+                                       else
+                                               return new UnboxCast (source, target_type);
+                               }
+
+                               return null;
+                       }
+                       
+                       // From an array type S with an element type Se to an array type T with an 
+                       // element type Te provided all the following are true:
+                       //     * S and T differe only in element type, in other words, S and T
+                       //       have the same number of dimensions.
+                       //     * Both Se and Te are reference types
+                       //     * An explicit referenc conversions exist from Se to Te
+                       //
+                       if (source_type.IsArray && target_type.IsArray) {
+                               if (source_type.GetArrayRank () == target_type.GetArrayRank ()) {
+                                       
+                                       Type source_element_type = TypeManager.GetElementType (source_type);
+                                       Type target_element_type = TypeManager.GetElementType (target_type);
+                                       
+                                       if (!source_element_type.IsValueType && !target_element_type.IsValueType)
+                                               if (ExplicitReferenceConversionExists (source_element_type,
+                                                                                      target_element_type))
+                                                       return new ClassCast (source, target_type);
+                               }
+                       }
+                       
+
+                       // From System.Array to any array-type
+                       if (source_type == TypeManager.array_type &&
+                           target_type.IsArray) {
+                               return new ClassCast (source, target_type);
+                       }
+
+                       //
+                       // From System delegate to any delegate-type
+                       //
+                       if (source_type == TypeManager.delegate_type &&
+                           TypeManager.IsDelegateType (target_type))
+                               return new ClassCast (source, target_type);
+
+                       //
+                       // From ICloneable to Array or Delegate types
+                       //
+                       if (source_type == TypeManager.icloneable_type &&
+                           (target_type == TypeManager.array_type ||
+                            target_type == TypeManager.delegate_type))
+                               return new ClassCast (source, target_type);
+                       
+                       return null;
+               }
+               
+               /// <summary>
+               ///   Performs an explicit conversion of the expression `expr' whose
+               ///   type is expr.Type to `target_type'.
+               /// </summary>
+               static public Expression ExplicitConversion (EmitContext ec, Expression expr,
+                                                            Type target_type, Location loc)
+               {
+                       Type expr_type = expr.Type;
+                       Type original_expr_type = expr_type;
+
+                       if (expr_type.IsSubclassOf (TypeManager.enum_type)){
+                               if (target_type == TypeManager.enum_type ||
+                                   target_type == TypeManager.object_type) {
+                                       if (expr is EnumConstant)
+                                               expr = ((EnumConstant) expr).Child;
+                                       // We really need all these casts here .... :-(
+                                       expr = new BoxedCast (new EmptyCast (expr, expr_type));
+                                       return new EmptyCast (expr, target_type);
+                               } else if ((expr_type == TypeManager.enum_type) && target_type.IsValueType &&
+                                          target_type.IsSubclassOf (TypeManager.enum_type))
+                                       return new UnboxCast (expr, target_type);
+
+                               //
+                               // Notice that we have kept the expr_type unmodified, which is only
+                               // used later on to 
+                               if (expr is EnumConstant)
+                                       expr = ((EnumConstant) expr).Child;
+                               else
+                                       expr = new EmptyCast (expr, TypeManager.EnumToUnderlying (expr_type));
+                               expr_type = expr.Type;
+                       }
+
+                       int errors = Report.Errors;
+                       Expression ne = ImplicitConversionStandard (ec, expr, target_type, loc);
+                       if (Report.Errors > errors)
+                               return null;
+
+                       if (ne != null)
+                               return ne;
+
+                       ne = ExplicitNumericConversion (ec, expr, target_type, loc);
+                       if (ne != null)
+                               return ne;
+
+                       //
+                       // Unboxing conversion.
+                       //
+                       if (expr_type == TypeManager.object_type && target_type.IsValueType)
+                               return new UnboxCast (expr, target_type);
+
+                       //
+                       // Skip the ExplicitReferenceConversion because we can not convert
+                       // from Null to a ValueType, and ExplicitReference wont check against
+                       // null literal explicitly
+                       //
+                       if (expr_type != TypeManager.null_type){
+                               ne = ExplicitReferenceConversion (expr, target_type);
+                               if (ne != null)
+                                       return ne;
+                       }
+
+               skip_explicit:
+                       if (ec.InUnsafe){
+                               if (target_type.IsPointer){
+                                       if (expr_type.IsPointer)
+                                               return new EmptyCast (expr, target_type);
+                                       
+                                       if (expr_type == TypeManager.sbyte_type ||
+                                           expr_type == TypeManager.byte_type ||
+                                           expr_type == TypeManager.short_type ||
+                                           expr_type == TypeManager.ushort_type ||
+                                           expr_type == TypeManager.int32_type ||
+                                           expr_type == TypeManager.uint32_type ||
+                                           expr_type == TypeManager.uint64_type ||
+                                           expr_type == TypeManager.int64_type)
+                                               return new OpcodeCast (expr, target_type, OpCodes.Conv_U);
+                               }
+                               if (expr_type.IsPointer){
+                                       Expression e = null;
+                                       
+                                       if (target_type == TypeManager.sbyte_type)
+                                               e = new OpcodeCast (expr, target_type, OpCodes.Conv_I1);
+                                       else if (target_type == TypeManager.byte_type)
+                                               e = new OpcodeCast (expr, target_type, OpCodes.Conv_U1);
+                                       else if (target_type == TypeManager.short_type)
+                                               e = new OpcodeCast (expr, target_type, OpCodes.Conv_I2);
+                                       else if (target_type == TypeManager.ushort_type)
+                                               e = new OpcodeCast (expr, target_type, OpCodes.Conv_U2);
+                                       else if (target_type == TypeManager.int32_type)
+                                               e = new OpcodeCast (expr, target_type, OpCodes.Conv_I4);
+                                       else if (target_type == TypeManager.uint32_type)
+                                               e = new OpcodeCast (expr, target_type, OpCodes.Conv_U4);
+                                       else if (target_type == TypeManager.uint64_type)
+                                               e = new OpcodeCast (expr, target_type, OpCodes.Conv_U8);
+                                       else if (target_type == TypeManager.int64_type){
+                                               e = new OpcodeCast (expr, target_type, OpCodes.Conv_I8);
+                                       }
+
+                                       if (e != null){
+                                               Expression ci, ce;
+
+                                               ci = ImplicitConversionStandard (ec, e, target_type, loc);
+
+                                               if (ci != null)
+                                                       return ci;
+
+                                               ce = ExplicitNumericConversion (ec, e, target_type, loc);
+                                               if (ce != null)
+                                                       return ce;
+                                               //
+                                               // We should always be able to go from an uint32
+                                               // implicitly or explicitly to the other integral
+                                               // types
+                                               //
+                                               throw new Exception ("Internal compiler error");
+                                       }
+                               }
+                       }
+                       
+                       ne = ExplicitUserConversion (ec, expr, target_type, loc);
+                       if (ne != null)
+                               return ne;
+
+                       if (expr is NullLiteral){
+                               Report.Error (37, loc, "Cannot convert null to value type `" +
+                                             TypeManager.CSharpName (target_type) + "'");
+                               return null;
+                       }
+                               
+                       Error_CannotConvertType (loc, original_expr_type, target_type);
+                       return null;
+               }
+
+               /// <summary>
+               ///   Same as ExplicitConversion, only it doesn't include user defined conversions
+               /// </summary>
+               static public Expression ExplicitConversionStandard (EmitContext ec, Expression expr,
+                                                                    Type target_type, Location l)
+               {
+                       int errors = Report.Errors;
+                       Expression ne = ImplicitConversionStandard (ec, expr, target_type, l);
+                       if (Report.Errors > errors)
+                               return null;
+
+                       if (ne != null)
+                               return ne;
+
+                       ne = ExplicitNumericConversion (ec, expr, target_type, l);
+                       if (ne != null)
+                               return ne;
+
+                       ne = ExplicitReferenceConversion (expr, target_type);
+                       if (ne != null)
+                               return ne;
+
+                       Error_CannotConvertType (l, expr.Type, target_type);
+                       return null;
+               }
+       }
+}
diff --git a/mcs/bmcs/decl.cs b/mcs/bmcs/decl.cs
new file mode 100644 (file)
index 0000000..0ca658d
--- /dev/null
@@ -0,0 +1,2383 @@
+//
+// decl.cs: Declaration base class for structs, classes, enums and interfaces.
+//
+// Author: Miguel de Icaza (miguel@gnu.org)
+//         Marek Safar (marek.safar@seznam.cz)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
+//
+// TODO: Move the method verification stuff from the class.cs and interface.cs here
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Globalization;
+using System.Reflection.Emit;
+using System.Reflection;
+using System.Xml;
+
+namespace Mono.CSharp {
+
+       public class MemberName {
+               public string Name;
+               public readonly TypeArguments TypeArguments;
+
+               public readonly MemberName Left;
+
+               public static readonly MemberName Null = new MemberName ("");
+
+               public MemberName (string name)
+               {
+                       this.Name = name;
+               }
+
+               public MemberName (string name, TypeArguments args)
+                       : this (name)
+               {
+                       this.TypeArguments = args;
+               }
+
+               public MemberName (MemberName left, string name, TypeArguments args)
+                       : this (name, args)
+               {
+                       this.Left = left;
+               }
+
+               public MemberName (MemberName left, MemberName right)
+                       : this (left, right.Name, right.TypeArguments)
+               {
+               }
+
+               public string GetName ()
+               {
+                       if (Left != null)
+                               return Left.GetName () + "." + Name;
+                       else
+                               return Name;
+               }
+
+               public bool IsGeneric {
+                       get {
+                               if (TypeArguments != null)
+                                       return true;
+                               else if (Left != null)
+                                       return Left.IsGeneric;
+                               else
+                                       return false;
+                       }
+               }
+
+               public string GetName (bool is_generic)
+               {
+                       string name = is_generic ? Basename : Name;
+                       if (Left != null)
+                               return Left.GetName (is_generic) + "." + name;
+                       else
+                               return name;
+               }
+
+               public int CountTypeArguments {
+                       get {
+                               if (TypeArguments == null)
+                                       return 0;
+                               else
+                                       return TypeArguments.Count;
+                       }
+               }
+
+               public string GetMethodName ()
+               {
+                       if (Left != null)
+                               return Left.GetTypeName () + "." + Name;
+                       else
+                               return Name;
+               }
+
+               public static string MakeName (string name, TypeArguments args)
+               {
+                       if (args == null)
+                               return name;
+                       else
+                               return name + "`" + args.Count;
+               }
+
+               public static string MakeName (string name, int count)
+               {
+                       return name + "`" + count;
+               }
+
+               public string GetTypeName ()
+               {
+                       string suffix = "";
+                       if (Left != null)
+                               return Left.GetTypeName () + "." +
+                                       MakeName (Name, TypeArguments);
+                       else
+                               return MakeName (Name, TypeArguments);
+               }
+
+               protected bool IsUnbound {
+                       get {
+                               if ((Left != null) && Left.IsUnbound)
+                                       return true;
+                               else if (TypeArguments == null)
+                                       return false;
+                               else
+                                       return TypeArguments.IsUnbound;
+                       }
+               }
+
+               protected bool CheckUnbound (Location loc)
+               {
+                       if ((Left != null) && !Left.CheckUnbound (loc))
+                               return false;
+                       if ((TypeArguments != null) && !TypeArguments.IsUnbound) {
+                               Report.Error (1031, loc, "Type expected");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               public Expression GetTypeExpression (Location loc)
+               {
+                       if (IsUnbound) {
+                               if (!CheckUnbound (loc))
+                                       return null;
+
+                               return new UnboundTypeExpression (GetTypeName ());
+                       }
+
+                       if (Left != null) {
+                               Expression lexpr = Left.GetTypeExpression (loc);
+
+                               return new MemberAccess (lexpr, Name, TypeArguments, loc);
+                       } else {
+                               if (TypeArguments != null)
+                                       return new ConstructedType (Name, TypeArguments, loc);
+                               else
+                                       return new SimpleName (Name, loc);
+                       }
+               }
+
+               public MemberName Clone ()
+               {
+                       if (Left != null)
+                               return new MemberName (Left.Clone (), Name, TypeArguments);
+                       else
+                               return new MemberName (Name, TypeArguments);
+               }
+
+               public string Basename {
+                       get {
+                               if (TypeArguments != null)
+                                       return MakeName (Name, TypeArguments);
+                               else
+                                       return Name;
+                       }
+               }
+
+               public override string ToString ()
+               {
+                       string full_name;
+                       if (TypeArguments != null)
+                               full_name = Name + "<" + TypeArguments + ">";
+                       else
+                               full_name = Name;
+
+                       if (Left != null)
+                               return Left + "." + full_name;
+                       else
+                               return full_name;
+               }
+       }
+
+       /// <summary>
+       ///   Base representation for members.  This is used to keep track
+       ///   of Name, Location and Modifier flags, and handling Attributes.
+       /// </summary>
+       public abstract class MemberCore : Attributable {
+               /// <summary>
+               ///   Public name
+               /// </summary>
+               public string Name {
+                       get {
+                               return MemberName.GetName (!(this is GenericMethod) && !(this is Method));
+                       }
+               }
+
+                // Is not readonly because of IndexerName attribute
+               public MemberName MemberName;
+
+               /// <summary>
+               ///   Modifier flags that the user specified in the source code
+               /// </summary>
+               public int ModFlags;
+
+               public readonly TypeContainer Parent;
+
+               /// <summary>
+               ///   Location where this declaration happens
+               /// </summary>
+               public readonly Location Location;
+
+               /// <summary>
+               ///   XML documentation comment
+               /// </summary>
+               public string DocComment;
+
+               /// <summary>
+               ///   Represents header string for documentation comment 
+               ///   for each member types.
+               /// </summary>
+               public abstract string DocCommentHeader { get; }
+
+               [Flags]
+               public enum Flags {
+                       Obsolete_Undetected = 1,                // Obsolete attribute has not been detected yet
+                       Obsolete = 1 << 1,                      // Type has obsolete attribute
+                       ClsCompliance_Undetected = 1 << 2,      // CLS Compliance has not been detected yet
+                       ClsCompliant = 1 << 3,                  // Type is CLS Compliant
+                       CloseTypeCreated = 1 << 4,              // Tracks whether we have Closed the type
+                       HasCompliantAttribute_Undetected = 1 << 5,      // Presence of CLSCompliantAttribute has not been detected
+                       HasClsCompliantAttribute = 1 << 6,                      // Type has CLSCompliantAttribute
+                       ClsCompliantAttributeTrue = 1 << 7,                     // Type has CLSCompliant (true)
+                       Excluded_Undetected = 1 << 8,           // Conditional attribute has not been detected yet
+                       Excluded = 1 << 9,                                      // Method is conditional
+                       TestMethodDuplication = 1 << 10         // Test for duplication must be performed
+               }
+  
+               /// <summary>
+               ///   MemberCore flags at first detected then cached
+               /// </summary>
+               internal Flags caching_flags;
+
+               public MemberCore (TypeContainer parent, MemberName name, Attributes attrs,
+                                  Location loc)
+                       : base (attrs)
+               {
+                       Parent = parent;
+                       MemberName = name;
+                       Location = loc;
+                       caching_flags = Flags.Obsolete_Undetected | Flags.ClsCompliance_Undetected | Flags.HasCompliantAttribute_Undetected | Flags.Excluded_Undetected;
+               }
+
+               /// <summary>
+               /// Tests presence of ObsoleteAttribute and report proper error
+               /// </summary>
+               protected void CheckUsageOfObsoleteAttribute (Type type)
+               {
+                       if (type == null)
+                               return;
+
+                       ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (type);
+                       if (obsolete_attr == null)
+                               return;
+
+                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, type.FullName, Location);
+               }
+
+               public abstract bool Define ();
+
+               // 
+               // Returns full member name for error message
+               //
+               public virtual string GetSignatureForError ()
+               {
+                       return Name;
+               }
+
+               /// <summary>
+               /// Use this method when MethodBuilder is null
+               /// </summary>
+               public virtual string GetSignatureForError (TypeContainer tc)
+               {
+                       return Name;
+               }
+
+               /// <summary>
+               /// Base Emit method. This is also entry point for CLS-Compliant verification.
+               /// </summary>
+               public virtual void Emit ()
+               {
+                       // Hack with Parent == null is for EnumMember
+                       if (Parent == null || (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent) == null))
+                               VerifyObsoleteAttribute ();
+
+                       if (!RootContext.VerifyClsCompliance)
+                               return;
+
+                       VerifyClsCompliance (Parent);
+               }
+
+               public bool InUnsafe {
+                       get {
+                               return ((ModFlags & Modifiers.UNSAFE) != 0) || Parent.UnsafeContext;
+                       }
+               }
+
+               // 
+               // Whehter is it ok to use an unsafe pointer in this type container
+               //
+               public bool UnsafeOK (DeclSpace parent)
+               {
+                       //
+                       // First check if this MemberCore modifier flags has unsafe set
+                       //
+                       if ((ModFlags & Modifiers.UNSAFE) != 0)
+                               return true;
+
+                       if (parent.UnsafeContext)
+                               return true;
+
+                       Expression.UnsafeError (Location);
+                       return false;
+               }
+
+               /// <summary>
+               /// Returns instance of ObsoleteAttribute for this MemberCore
+               /// </summary>
+               public ObsoleteAttribute GetObsoleteAttribute (DeclSpace ds)
+               {
+                       // ((flags & (Flags.Obsolete_Undetected | Flags.Obsolete)) == 0) is slower, but why ?
+                       if ((caching_flags & Flags.Obsolete_Undetected) == 0 && (caching_flags & Flags.Obsolete) == 0) {
+                               return null;
+                       }
+
+                       caching_flags &= ~Flags.Obsolete_Undetected;
+
+                       if (OptAttributes == null)
+                               return null;
+
+                       Attribute obsolete_attr = OptAttributes.Search (
+                               TypeManager.obsolete_attribute_type, ds.EmitContext);
+                       if (obsolete_attr == null)
+                               return null;
+
+                       ObsoleteAttribute obsolete = obsolete_attr.GetObsoleteAttribute (ds);
+                       if (obsolete == null)
+                               return null;
+
+                       caching_flags |= Flags.Obsolete;
+                       return obsolete;
+               }
+
+               /// <summary>
+               /// Analyze whether CLS-Compliant verification must be execute for this MemberCore.
+               /// </summary>
+               public override bool IsClsCompliaceRequired (DeclSpace container)
+               {
+                       if ((caching_flags & Flags.ClsCompliance_Undetected) == 0)
+                               return (caching_flags & Flags.ClsCompliant) != 0;
+
+                       if (GetClsCompliantAttributeValue (container) && IsExposedFromAssembly (container)) {
+                               caching_flags &= ~Flags.ClsCompliance_Undetected;
+                               caching_flags |= Flags.ClsCompliant;
+                               return true;
+                       }
+
+                       caching_flags &= ~Flags.ClsCompliance_Undetected;
+                       return false;
+               }
+
+               /// <summary>
+               /// Returns true when MemberCore is exposed from assembly.
+               /// </summary>
+               public bool IsExposedFromAssembly (DeclSpace ds)
+               {
+                       if ((ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
+                               return false;
+                       
+                       DeclSpace parentContainer = ds;
+                       while (parentContainer != null && parentContainer.ModFlags != 0) {
+                               if ((parentContainer.ModFlags & (Modifiers.PUBLIC | Modifiers.PROTECTED)) == 0)
+                                       return false;
+                               parentContainer = parentContainer.Parent;
+                       }
+                       return true;
+               }
+
+               /// <summary>
+               /// Resolve CLSCompliantAttribute value or gets cached value.
+               /// </summary>
+               bool GetClsCompliantAttributeValue (DeclSpace ds)
+               {
+                       if (OptAttributes != null) {
+                               Attribute cls_attribute = OptAttributes.Search (
+                                       TypeManager.cls_compliant_attribute_type, ds.EmitContext);
+                               if (cls_attribute != null) {
+                                       caching_flags |= Flags.HasClsCompliantAttribute;
+                                       return cls_attribute.GetClsCompliantAttributeValue (ds);
+                               }
+                       }
+                       return ds.GetClsCompliantAttributeValue ();
+               }
+
+               /// <summary>
+               /// Returns true if MemberCore is explicitly marked with CLSCompliantAttribute
+               /// </summary>
+               protected bool HasClsCompliantAttribute {
+                       get {
+                               return (caching_flags & Flags.HasClsCompliantAttribute) != 0;
+                       }
+               }
+
+               /// <summary>
+               /// The main virtual method for CLS-Compliant verifications.
+               /// The method returns true if member is CLS-Compliant and false if member is not
+               /// CLS-Compliant which means that CLS-Compliant tests are not necessary. A descendants override it
+               /// and add their extra verifications.
+               /// </summary>
+               protected virtual bool VerifyClsCompliance (DeclSpace ds)
+               {
+                       if (!IsClsCompliaceRequired (ds)) {
+                               if ((RootContext.WarningLevel >= 2) && HasClsCompliantAttribute && !IsExposedFromAssembly (ds)) {
+                                       Report.Warning (3019, Location, "CLS compliance checking will not be performed on '{0}' because it is private or internal", GetSignatureForError ());
+                               }
+                               return false;
+                       }
+
+                       if (!CodeGen.Assembly.IsClsCompliant) {
+                               if (HasClsCompliantAttribute) {
+                                       Report.Error (3014, Location, "'{0}' cannot be marked as CLS-compliant because the assembly does not have a CLSCompliant attribute", GetSignatureForError ());
+                               }
+                               return false;
+                       }
+
+                       int index = Name.LastIndexOf ('.');
+                       if (Name [index > 0 ? index + 1 : 0] == '_') {
+                               Report.Error (3008, Location, "Identifier '{0}' is not CLS-compliant", GetSignatureForError () );
+                       }
+                       return true;
+               }
+
+               protected abstract void VerifyObsoleteAttribute ();
+
+               //
+               // Raised (and passed an XmlElement that contains the comment)
+               // when GenerateDocComment is writing documentation expectedly.
+               //
+               internal virtual void OnGenerateDocComment (DeclSpace ds, XmlElement intermediateNode)
+               {
+               }
+
+               //
+               // Returns a string that represents the signature for this 
+               // member which should be used in XML documentation.
+               //
+               public virtual string GetDocCommentName (DeclSpace ds)
+               {
+                       if (ds == null || this is DeclSpace)
+                               return DocCommentHeader + Name;
+                       else
+                               return String.Concat (DocCommentHeader, ds.Name, ".", Name);
+               }
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal virtual void GenerateDocComment (DeclSpace ds)
+               {
+                       DocUtil.GenerateDocComment (this, ds);
+               }
+       }
+
+       /// <summary>
+       ///   Base class for structs, classes, enumerations and interfaces.  
+       /// </summary>
+       /// <remarks>
+       ///   They all create new declaration spaces.  This
+       ///   provides the common foundation for managing those name
+       ///   spaces.
+       /// </remarks>
+       public abstract class DeclSpace : MemberCore, IAlias {
+               /// <summary>
+               ///   This points to the actual definition that is being
+               ///   created with System.Reflection.Emit
+               /// </summary>
+               public TypeBuilder TypeBuilder;
+
+               /// <summary>
+               ///   If we are a generic type, this is the type we are
+               ///   currently defining.  We need to lookup members on this
+               ///   instead of the TypeBuilder.
+               /// </summary>
+               public Type CurrentType;
+
+               //
+               // This is the namespace in which this typecontainer
+               // was declared.  We use this to resolve names.
+               //
+               public NamespaceEntry NamespaceEntry;
+
+               public Hashtable Cache = new Hashtable ();
+               
+               public string Basename;
+               
+               protected Hashtable defined_names;
+
+               readonly bool is_generic;
+               readonly int count_type_params;
+
+               // The emit context for toplevel objects.
+               protected EmitContext ec;
+               
+               public EmitContext EmitContext {
+                       get { return ec; }
+               }
+
+               //
+               // Whether we are Generic
+               //
+               public bool IsGeneric {
+                       get {
+                               if (is_generic)
+                                       return true;
+                               else if (Parent != null)
+                                       return Parent.IsGeneric;
+                               else
+                                       return false;
+                       }
+               }
+
+               static string[] attribute_targets = new string [] { "type" };
+
+               public DeclSpace (NamespaceEntry ns, TypeContainer parent, MemberName name,
+                                 Attributes attrs, Location l)
+                       : base (parent, name, attrs, l)
+               {
+                       NamespaceEntry = ns;
+                       Basename = name.Name;
+                       defined_names = new Hashtable ();
+                       if (name.TypeArguments != null) {
+                               is_generic = true;
+                               count_type_params = name.TypeArguments.Count;
+                       }
+                       if (parent != null)
+                               count_type_params += parent.count_type_params;
+               }
+
+               /// <summary>
+               /// Adds the member to defined_names table. It tests for duplications and enclosing name conflicts
+               /// </summary>
+               protected bool AddToContainer (MemberCore symbol, bool is_method, string fullname, string basename)
+               {
+                       if (basename == Basename && !(this is Interface)) {
+                               if (symbol is TypeParameter)
+                                       Report.Error (694, "Type parameter `{0}' has same name as " +
+                                                     "containing type or method", basename);
+                               else {
+                                       Report.SymbolRelatedToPreviousError (this);
+                                       Report.Error (542, "'{0}': member names cannot be the same as their " +
+                                                     "enclosing type", symbol.Location, symbol.GetSignatureForError ());
+                               }
+                               return false;
+                       }
+
+                       MemberCore mc = (MemberCore)defined_names [fullname];
+
+                       if (is_method && (mc is MethodCore || mc is IMethodData)) {
+                               symbol.caching_flags |= Flags.TestMethodDuplication;
+                               mc.caching_flags |= Flags.TestMethodDuplication;
+                               return true;
+                       }
+
+                       if (mc != null) {
+                               if (symbol is TypeParameter)
+                                       Report.Error (692, symbol.Location, "Duplicate type parameter `{0}'", basename);
+                               else {
+                                       Report.SymbolRelatedToPreviousError (mc);
+                                       Report.Error (102, symbol.Location,
+                                                     "The type '{0}' already contains a definition for '{1}'",
+                                                     GetSignatureForError (), basename);
+                               }
+                               return false;
+                       }
+
+                       defined_names.Add (fullname, symbol);
+                       return true;
+               }
+
+               public void RecordDecl ()
+               {
+                       if ((NamespaceEntry != null) && (Parent == RootContext.Tree.Types))
+                               NamespaceEntry.DefineName (MemberName.Basename, this);
+               }
+
+               /// <summary>
+               ///   Returns the MemberCore associated with a given name in the declaration
+               ///   space. It doesn't return method based symbols !!
+               /// </summary>
+               /// 
+               public MemberCore GetDefinition (string name)
+               {
+                       return (MemberCore)defined_names [name];
+               }
+
+               bool in_transit = false;
+               
+               /// <summary>
+               ///   This function is used to catch recursive definitions
+               ///   in declarations.
+               /// </summary>
+               public bool InTransit {
+                       get {
+                               return in_transit;
+                       }
+
+                       set {
+                               in_transit = value;
+                       }
+               }
+
+               /// <summary>
+               ///   Looks up the alias for the name
+               /// </summary>
+               public IAlias LookupAlias (string name)
+               {
+                       if (NamespaceEntry != null)
+                               return NamespaceEntry.LookupAlias (name);
+                       else
+                               return null;
+               }
+               
+               // 
+               // root_types contains all the types.  All TopLevel types
+               // hence have a parent that points to `root_types', that is
+               // why there is a non-obvious test down here.
+               //
+               public bool IsTopLevel {
+                       get {
+                               if (Parent != null){
+                                       if (Parent.Parent == null)
+                                               return true;
+                               }
+                               return false;
+                       }
+               }
+
+               public virtual void CloseType ()
+               {
+                       if ((caching_flags & Flags.CloseTypeCreated) == 0){
+                               try {
+                                       TypeBuilder.CreateType ();
+                               } catch {
+                                       //
+                                       // The try/catch is needed because
+                                       // nested enumerations fail to load when they
+                                       // are defined.
+                                       //
+                                       // Even if this is the right order (enumerations
+                                       // declared after types).
+                                       //
+                                       // Note that this still creates the type and
+                                       // it is possible to save it
+                               }
+                               caching_flags |= Flags.CloseTypeCreated;
+                       }
+               }
+
+               /// <remarks>
+               ///  Should be overriten by the appropriate declaration space
+               /// </remarks>
+               public abstract TypeBuilder DefineType ();
+               
+               /// <summary>
+               ///   Define all members, but don't apply any attributes or do anything which may
+               ///   access not-yet-defined classes.  This method also creates the MemberCache.
+               /// </summary>
+               public abstract bool DefineMembers (TypeContainer parent);
+
+               //
+               // Whether this is an `unsafe context'
+               //
+               public bool UnsafeContext {
+                       get {
+                               if ((ModFlags & Modifiers.UNSAFE) != 0)
+                                       return true;
+                               if (Parent != null)
+                                       return Parent.UnsafeContext;
+                               return false;
+                       }
+               }
+
+               public static string MakeFQN (string nsn, string name)
+               {
+                       if (nsn == "")
+                               return name;
+                       return String.Concat (nsn, ".", name);
+               }
+
+               EmitContext type_resolve_ec;
+               EmitContext GetTypeResolveEmitContext (TypeContainer parent, Location loc)
+               {
+                       type_resolve_ec = new EmitContext (parent, this, loc, null, null, ModFlags, false);
+                       type_resolve_ec.ResolvingTypeTree = true;
+
+                       return type_resolve_ec;
+               }
+
+               public Type ResolveNestedType (Type t, Location loc)
+               {
+                       TypeContainer tc = TypeManager.LookupTypeContainer (t);
+                       if ((tc != null) && tc.IsGeneric) {
+                               if (!IsGeneric) {
+                                       int tnum = TypeManager.GetNumberOfTypeArguments (t);
+                                       Report.Error (305, loc,
+                                                     "Using the generic type `{0}' " +
+                                                     "requires {1} type arguments",
+                                                     TypeManager.GetFullName (t), tnum);
+                                       return null;
+                               }
+
+                               TypeParameter[] args;
+                               if (this is GenericMethod)
+                                       args = Parent.TypeParameters;
+                               else
+                                       args = TypeParameters;
+
+                               TypeExpr ctype = new ConstructedType (t, args, loc);
+                               ctype = ctype.ResolveAsTypeTerminal (ec);
+                               if (ctype == null)
+                                       return null;
+
+                               t = ctype.Type;
+                       }
+
+                       return t;
+               }
+
+               // <summary>
+               //    Resolves the expression `e' for a type, and will recursively define
+               //    types.  This should only be used for resolving base types.
+               // </summary>
+               public TypeExpr ResolveTypeExpr (Expression e, Location loc)
+               {
+                       if (type_resolve_ec == null)
+                               type_resolve_ec = GetTypeResolveEmitContext (Parent, loc);
+                       type_resolve_ec.loc = loc;
+                       if (this is GenericMethod)
+                               type_resolve_ec.ContainerType = Parent.TypeBuilder;
+                       else
+                               type_resolve_ec.ContainerType = TypeBuilder;
+
+                       return e.ResolveAsTypeTerminal (type_resolve_ec);
+               }
+               
+               public bool CheckAccessLevel (Type check_type) 
+               {
+                       TypeBuilder tb;
+                       if ((this is GenericMethod) || (this is Iterator))
+                               tb = Parent.TypeBuilder;
+                       else
+                               tb = TypeBuilder;
+
+                       if (check_type.IsGenericInstance)
+                               check_type = check_type.GetGenericTypeDefinition ();
+
+                       if (check_type == tb)
+                               return true;
+
+                       if (TypeBuilder == null)
+                               // FIXME: TypeBuilder will be null when invoked by Class.GetNormalBases().
+                               //        However, this is invoked again later -- so safe to return true.
+                               //        May also be null when resolving top-level attributes.
+                               return true;
+
+                       if (check_type.IsGenericParameter)
+                               return true; // FIXME
+                       
+                       TypeAttributes check_attr = check_type.Attributes & TypeAttributes.VisibilityMask;
+                       
+                       //
+                       // Broken Microsoft runtime, return public for arrays, no matter what 
+                       // the accessibility is for their underlying class, and they return 
+                       // NonPublic visibility for pointers
+                       //
+                       if (check_type.IsArray || check_type.IsPointer)
+                               return CheckAccessLevel (TypeManager.GetElementType (check_type));
+
+                       switch (check_attr){
+                       case TypeAttributes.Public:
+                               return true;
+
+                       case TypeAttributes.NotPublic:
+
+                               if (TypeBuilder == null)
+                                       // FIXME: TypeBuilder will be null when invoked by Class.GetNormalBases().
+                                       //        However, this is invoked again later -- so safe to return true.
+                                       //        May also be null when resolving top-level attributes.
+                                       return true;
+                               //
+                               // This test should probably use the declaringtype.
+                               //
+                               return check_type.Assembly == TypeBuilder.Assembly;
+
+                       case TypeAttributes.NestedPublic:
+                               return true;
+
+                       case TypeAttributes.NestedPrivate:
+                               return NestedAccessible (tb, check_type);
+
+                       case TypeAttributes.NestedFamily:
+                               //
+                               // Only accessible to methods in current type or any subtypes
+                               //
+                               return FamilyAccessible (tb, check_type);
+
+                       case TypeAttributes.NestedFamANDAssem:
+                               return (check_type.Assembly == tb.Assembly) &&
+                                       FamilyAccessible (tb, check_type);
+
+                       case TypeAttributes.NestedFamORAssem:
+                               return (check_type.Assembly == tb.Assembly) ||
+                                       FamilyAccessible (tb, check_type);
+
+                       case TypeAttributes.NestedAssembly:
+                               return check_type.Assembly == tb.Assembly;
+                       }
+
+                       Console.WriteLine ("HERE: " + check_attr);
+                       return false;
+
+               }
+
+               protected bool NestedAccessible (Type tb, Type check_type)
+               {
+                       string check_type_name = check_type.FullName;
+                       
+                       // At this point, we already know check_type is a nested class.
+                       int cio = check_type_name.LastIndexOf ('+');
+                       
+                       // Ensure that the string 'container' has a '+' in it to avoid false matches
+                       string container = check_type_name.Substring (0, cio + 1);
+
+                       // Ensure that type_name ends with a '+' so that it can match 'container', if necessary
+                       string type_name = tb.FullName + "+";
+
+                       // If the current class is nested inside the container of check_type,
+                       // we can access check_type even if it is private or protected.
+                       return type_name.StartsWith (container);
+               }
+
+               protected bool FamilyAccessible (Type tb, Type check_type)
+               {
+                       Type declaring = check_type.DeclaringType;
+                       if (tb == declaring || TypeManager.IsFamilyAccessible (tb, declaring))
+                               return true;
+
+                       return NestedAccessible (tb, check_type);
+               }
+
+               // Access level of a type.
+               const int X = 1;
+               enum AccessLevel { // Each column represents `is this scope larger or equal to Blah scope'
+                       // Public    Assembly   Protected
+                       Protected           = (0 << 0) | (0 << 1) | (X << 2),
+                       Public              = (X << 0) | (X << 1) | (X << 2),
+                       Private             = (0 << 0) | (0 << 1) | (0 << 2),
+                       Internal            = (0 << 0) | (X << 1) | (0 << 2),
+                       ProtectedOrInternal = (0 << 0) | (X << 1) | (X << 2),
+               }
+
+               static AccessLevel GetAccessLevelFromModifiers (int flags)
+               {
+                       if ((flags & Modifiers.INTERNAL) != 0) {
+
+                               if ((flags & Modifiers.PROTECTED) != 0)
+                                       return AccessLevel.ProtectedOrInternal;
+                               else
+                                       return AccessLevel.Internal;
+
+                       } else if ((flags & Modifiers.PROTECTED) != 0)
+                               return AccessLevel.Protected;
+                       else if ((flags & Modifiers.PRIVATE) != 0)
+                               return AccessLevel.Private;
+                       else
+                               return AccessLevel.Public;
+               }
+
+               // What is the effective access level of this?
+               // TODO: Cache this?
+               AccessLevel EffectiveAccessLevel {
+                       get {
+                               AccessLevel myAccess = GetAccessLevelFromModifiers (ModFlags);
+                               if (!IsTopLevel && (Parent != null))
+                                       return myAccess & Parent.EffectiveAccessLevel;
+                               return myAccess;
+                       }
+               }
+
+               // Return the access level for type `t'
+               static AccessLevel TypeEffectiveAccessLevel (Type t)
+               {
+                       if (t.IsPublic)
+                               return AccessLevel.Public;
+                       if (t.IsNestedPrivate)
+                               return AccessLevel.Private;
+                       if (t.IsNotPublic)
+                               return AccessLevel.Internal;
+
+                       // By now, it must be nested
+                       AccessLevel parentLevel = TypeEffectiveAccessLevel (t.DeclaringType);
+
+                       if (t.IsNestedPublic)
+                               return parentLevel;
+                       if (t.IsNestedAssembly)
+                               return parentLevel & AccessLevel.Internal;
+                       if (t.IsNestedFamily)
+                               return parentLevel & AccessLevel.Protected;
+                       if (t.IsNestedFamORAssem)
+                               return parentLevel & AccessLevel.ProtectedOrInternal;
+                       if (t.IsNestedFamANDAssem)
+                               throw new NotImplementedException ("NestedFamANDAssem not implemented, cant make this kind of type from c# anyways");
+
+                       // nested private is taken care of
+
+                       throw new Exception ("I give up, what are you?");
+               }
+
+               //
+               // This answers `is the type P, as accessible as a member M which has the
+               // accessability @flags which is declared as a nested member of the type T, this declspace'
+               //
+               public bool AsAccessible (Type p, int flags)
+               {
+                       if (p.IsGenericParameter)
+                               return true; // FIXME
+
+                       //
+                       // 1) if M is private, its accessability is the same as this declspace.
+                       // we already know that P is accessible to T before this method, so we
+                       // may return true.
+                       //
+
+                       if ((flags & Modifiers.PRIVATE) != 0)
+                               return true;
+
+                       while (p.IsArray || p.IsPointer || p.IsByRef)
+                               p = TypeManager.GetElementType (p);
+
+                       AccessLevel pAccess = TypeEffectiveAccessLevel (p);
+                       AccessLevel mAccess = this.EffectiveAccessLevel &
+                               GetAccessLevelFromModifiers (flags);
+
+                       // for every place from which we can access M, we must
+                       // be able to access P as well. So, we want
+                       // For every bit in M and P, M_i -> P_1 == true
+                       // or, ~ (M -> P) == 0 <-> ~ ( ~M | P) == 0
+
+                       return ~ (~ mAccess | pAccess) == 0;
+               }
+               
+               static DoubleHash dh = new DoubleHash (1000);
+
+               Type DefineTypeAndParents (DeclSpace tc)
+               {
+                       DeclSpace container = tc.Parent;
+
+                       if (container.TypeBuilder == null && container.Name != "")
+                               DefineTypeAndParents (container);
+
+                       return tc.DefineType ();
+               }
+               
+               Type LookupInterfaceOrClass (string ns, string name, out bool error)
+               {
+                       DeclSpace parent;
+                       Type t;
+                       object r;
+                       
+                       error = false;
+
+                       if (dh.Lookup (ns, name, out r))
+                               return (Type) r;
+                       else {
+                               if (ns != ""){
+                                       if (Namespace.IsNamespace (ns)){
+                                               string fullname = (ns != "") ? ns + "." + name : name;
+                                               t = TypeManager.LookupType (fullname);
+                                       } else
+                                               t = null;
+                               } else
+                                       t = TypeManager.LookupType (name);
+                       }
+                       
+                       if (t != null) {
+                               dh.Insert (ns, name, t);
+                               return t;
+                       }
+
+                       //
+                       // In case we are fed a composite name, normalize it.
+                       //
+                       int p = name.LastIndexOf ('.');
+                       if (p != -1){
+                               ns = MakeFQN (ns, name.Substring (0, p));
+                               name = name.Substring (p+1);
+                       }
+                       
+                       parent = RootContext.Tree.LookupByNamespace (ns, name);
+                       if (parent == null) {
+                               dh.Insert (ns, name, null);
+                               return null;
+                       }
+
+                       t = DefineTypeAndParents (parent);
+                       if (t == null){
+                               error = true;
+                               return null;
+                       }
+                       
+                       dh.Insert (ns, name, t);
+                       return t;
+               }
+
+               public static void Error_AmbiguousTypeReference (Location loc, string name, string t1, string t2)
+               {
+                       Report.Error (104, loc,
+                                     "`{0}' is an ambiguous reference ({1} or {2})",
+                                     name, t1, t2);
+               }
+
+               public Type FindNestedType (Location loc, string name,
+                                           out DeclSpace containing_ds)
+               {
+                       Type t;
+                       bool error;
+
+                       containing_ds = this;
+                       while (containing_ds != null){
+                               Type container_type = containing_ds.TypeBuilder;
+                               Type current_type = container_type;
+
+                               while (current_type != null && current_type != TypeManager.object_type) {
+                                       string pre = current_type.FullName;
+
+                                       t = LookupInterfaceOrClass (pre, name, out error);
+                                       if (error)
+                                               return null;
+
+                                       if ((t != null) && containing_ds.CheckAccessLevel (t))
+                                               return t;
+
+                                       current_type = current_type.BaseType;
+                               }
+                               containing_ds = containing_ds.Parent;
+                       }
+
+                       return null;
+               }
+
+               /// <summary>
+               ///   GetType is used to resolve type names at the DeclSpace level.
+               ///   Use this to lookup class/struct bases, interface bases or 
+               ///   delegate type references
+               /// </summary>
+               ///
+               /// <remarks>
+               ///   Contrast this to LookupType which is used inside method bodies to 
+               ///   lookup types that have already been defined.  GetType is used
+               ///   during the tree resolution process and potentially define
+               ///   recursively the type
+               /// </remarks>
+               public Type FindType (Location loc, string name)
+               {
+                       Type t;
+                       bool error;
+
+                       //
+                       // For the case the type we are looking for is nested within this one
+                       // or is in any base class
+                       //
+                       DeclSpace containing_ds = this;
+
+                       while (containing_ds != null){
+                               Type container_type = containing_ds.TypeBuilder;
+                               Type current_type = container_type;
+
+                               while (current_type != null && current_type != TypeManager.object_type) {
+                                       string pre = current_type.FullName;
+
+                                       t = LookupInterfaceOrClass (pre, name, out error);
+                                       if (error)
+                                               return null;
+
+                                       if ((t != null) && containing_ds.CheckAccessLevel (t))
+                                               return ResolveNestedType (t, loc);
+
+                                       current_type = current_type.BaseType;
+                               }
+                               containing_ds = containing_ds.Parent;
+                       }
+
+                       //
+                       // Attempt to lookup the class on our namespace and all it's implicit parents
+                       //
+                       for (NamespaceEntry ns = NamespaceEntry; ns != null; ns = ns.ImplicitParent) {
+                               t = LookupInterfaceOrClass (ns.FullName, name, out error);
+                               if (error)
+                                       return null;
+
+                               if (t != null)
+                                       return t;
+                       }
+                       
+                       //
+                       // Attempt to do a direct unqualified lookup
+                       //
+                       t = LookupInterfaceOrClass ("", name, out error);
+                       if (error)
+                               return null;
+                       
+                       if (t != null)
+                               return t;
+                       
+                       //
+                       // Attempt to lookup the class on any of the `using'
+                       // namespaces
+                       //
+
+                       for (NamespaceEntry ns = NamespaceEntry; ns != null; ns = ns.Parent){
+
+                               t = LookupInterfaceOrClass (ns.FullName, name, out error);
+                               if (error)
+                                       return null;
+
+                               if (t != null)
+                                       return t;
+
+                               if (name.IndexOf ('.') > 0)
+                                       continue;
+
+                               IAlias alias_value = ns.LookupAlias (name);
+                               if (alias_value != null) {
+                                       t = LookupInterfaceOrClass ("", alias_value.Name, out error);
+                                       if (error)
+                                               return null;
+
+                                       if (t != null)
+                                               return t;
+                               }
+
+                               //
+                               // Now check the using clause list
+                               //
+                               Type match = null;
+                               foreach (Namespace using_ns in ns.GetUsingTable ()) {
+                                       match = LookupInterfaceOrClass (using_ns.Name, name, out error);
+                                       if (error)
+                                               return null;
+
+                                       if (match != null) {
+                                               if (t != null){
+                                                       if (CheckAccessLevel (match)) {
+                                                               Error_AmbiguousTypeReference (loc, name, t.FullName, match.FullName);
+                                                               return null;
+                                                       }
+                                                       continue;
+                                               }
+                                               
+                                               t = match;
+                                       }
+                               }
+                               if (t != null)
+                                       return t;
+                       }
+
+                       //Report.Error (246, Location, "Can not find type `"+name+"'");
+                       return null;
+               }
+
+               /// <remarks>
+               ///   This function is broken and not what you're looking for.  It should only
+               ///   be used while the type is still being created since it doesn't use the cache
+               ///   and relies on the filter doing the member name check.
+               /// </remarks>
+               public abstract MemberList FindMembers (MemberTypes mt, BindingFlags bf,
+                                                       MemberFilter filter, object criteria);
+
+               /// <remarks>
+               ///   If we have a MemberCache, return it.  This property may return null if the
+               ///   class doesn't have a member cache or while it's still being created.
+               /// </remarks>
+               public abstract MemberCache MemberCache {
+                       get;
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       try {
+                               TypeBuilder.SetCustomAttribute (cb);
+                       } catch (System.ArgumentException e) {
+                               Report.Warning (-21, a.Location,
+                                               "The CharSet named property on StructLayout\n"+
+                                               "\tdoes not work correctly on Microsoft.NET\n"+
+                                               "\tYou might want to remove the CharSet declaration\n"+
+                                               "\tor compile using the Mono runtime instead of the\n"+
+                                               "\tMicrosoft .NET runtime\n"+
+                                               "\tThe runtime gave the error: " + e);
+                       }
+               }
+
+               /// <summary>
+               /// Goes through class hierarchy and get value of first CLSCompliantAttribute that found.
+               /// If no is attribute exists then return assembly CLSCompliantAttribute.
+               /// </summary>
+               public bool GetClsCompliantAttributeValue ()
+               {
+                       if ((caching_flags & Flags.HasCompliantAttribute_Undetected) == 0)
+                               return (caching_flags & Flags.ClsCompliantAttributeTrue) != 0;
+
+                       caching_flags &= ~Flags.HasCompliantAttribute_Undetected;
+
+                       if (OptAttributes != null) {
+                               Attribute cls_attribute = OptAttributes.Search (TypeManager.cls_compliant_attribute_type, ec);
+                               if (cls_attribute != null) {
+                                       caching_flags |= Flags.HasClsCompliantAttribute;
+                                       if (cls_attribute.GetClsCompliantAttributeValue (this)) {
+                                               caching_flags |= Flags.ClsCompliantAttributeTrue;
+                                               return true;
+                                       }
+                                       return false;
+                               }
+                       }
+
+                       if (Parent == null) {
+                               if (CodeGen.Assembly.IsClsCompliant) {
+                                       caching_flags |= Flags.ClsCompliantAttributeTrue;
+                                       return true;
+                               }
+                               return false;
+                       }
+
+                       if (Parent.GetClsCompliantAttributeValue ()) {
+                               caching_flags |= Flags.ClsCompliantAttributeTrue;
+                               return true;
+                       }
+                       return false;
+               }
+
+               //
+               // Extensions for generics
+               //
+               TypeParameter[] type_params;
+               TypeParameter[] type_param_list;
+
+               protected string GetInstantiationName ()
+               {
+                       StringBuilder sb = new StringBuilder (Name);
+                       sb.Append ("<");
+                       for (int i = 0; i < type_param_list.Length; i++) {
+                               if (i > 0)
+                                       sb.Append (",");
+                               sb.Append (type_param_list [i].Name);
+                       }
+                       sb.Append (">");
+                       return sb.ToString ();
+               }
+
+               bool check_type_parameter (ArrayList list, int start, string name)
+               {
+                       for (int i = 0; i < start; i++) {
+                               TypeParameter param = (TypeParameter) list [i];
+
+                               if (param.Name != name)
+                                       continue;
+
+                               if (RootContext.WarningLevel >= 3)
+                                       Report.Warning (
+                                               693, Location,
+                                               "Type parameter `{0}' has same name " +
+                                               "as type parameter from outer type `{1}'",
+                                               name, Parent.GetInstantiationName ());
+
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               TypeParameter[] initialize_type_params ()
+               {
+                       if (type_param_list != null)
+                               return type_param_list;
+
+                       DeclSpace the_parent = Parent;
+                       if (this is GenericMethod)
+                               the_parent = null;
+
+                       int start = 0;
+                       TypeParameter[] parent_params = null;
+                       if ((the_parent != null) && the_parent.IsGeneric) {
+                               parent_params = the_parent.initialize_type_params ();
+                               start = parent_params != null ? parent_params.Length : 0;
+                       }
+
+                       ArrayList list = new ArrayList ();
+                       if (parent_params != null)
+                               list.AddRange (parent_params);
+
+                       int count = type_params != null ? type_params.Length : 0;
+                       for (int i = 0; i < count; i++) {
+                               TypeParameter param = type_params [i];
+                               check_type_parameter (list, start, param.Name);
+                               list.Add (param);
+                       }
+
+                       type_param_list = new TypeParameter [list.Count];
+                       list.CopyTo (type_param_list, 0);
+                       return type_param_list;
+               }
+
+               public void SetParameterInfo (ArrayList constraints_list)
+               {
+                       if (!is_generic) {
+                               if (constraints_list != null) {
+                                       Report.Error (
+                                               80, Location, "Contraints are not allowed " +
+                                               "on non-generic declarations");
+                               }
+
+                               return;
+                       }
+
+                       string[] names = MemberName.TypeArguments.GetDeclarations ();
+                       type_params = new TypeParameter [names.Length];
+
+                       //
+                       // Register all the names
+                       //
+                       for (int i = 0; i < type_params.Length; i++) {
+                               string name = names [i];
+
+                               Constraints constraints = null;
+                               if (constraints_list != null) {
+                                       foreach (Constraints constraint in constraints_list) {
+                                               if (constraint.TypeParameter == name) {
+                                                       constraints = constraint;
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               type_params [i] = new TypeParameter (Parent, name, constraints, Location);
+
+                               string full_name = Name + "." + name;
+                               AddToContainer (type_params [i], false, full_name, name);
+                       }
+               }
+
+               public TypeParameter[] TypeParameters {
+                       get {
+                               if (!IsGeneric)
+                                       throw new InvalidOperationException ();
+                               if (type_param_list == null)
+                                       initialize_type_params ();
+
+                               return type_param_list;
+                       }
+               }
+
+               protected TypeParameter[] CurrentTypeParameters {
+                       get {
+                               if (!IsGeneric)
+                                       throw new InvalidOperationException ();
+                               if (type_params != null)
+                                       return type_params;
+                               else
+                                       return new TypeParameter [0];
+                       }
+               }
+
+               public int CountTypeParameters {
+                       get {
+                               return count_type_params;
+                       }
+               }
+
+               public TypeParameterExpr LookupGeneric (string name, Location loc)
+               {
+                       if (!IsGeneric)
+                               return null;
+
+                       foreach (TypeParameter type_param in CurrentTypeParameters) {
+                               if (type_param.Name != name)
+                                       continue;
+
+                               return new TypeParameterExpr (type_param, loc);
+                       }
+
+                       if (Parent != null)
+                               return Parent.LookupGeneric (name, loc);
+
+                       return null;
+               }
+
+               bool IAlias.IsType {
+                       get { return true; }
+               }
+
+               string IAlias.Name {
+                       get { return Name; }
+               }
+
+               TypeExpr IAlias.ResolveAsType (EmitContext ec)
+               {
+                       if (TypeBuilder == null)
+                               throw new InvalidOperationException ();
+
+                       if (CurrentType != null)
+                               return new TypeExpression (CurrentType, Location);
+                       else
+                               return new TypeExpression (TypeBuilder, Location);
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+       }
+
+       /// <summary>
+       ///   This is a readonly list of MemberInfo's.      
+       /// </summary>
+       public class MemberList : IList {
+               public readonly IList List;
+               int count;
+
+               /// <summary>
+               ///   Create a new MemberList from the given IList.
+               /// </summary>
+               public MemberList (IList list)
+               {
+                       if (list != null)
+                               this.List = list;
+                       else
+                               this.List = new ArrayList ();
+                       count = List.Count;
+               }
+
+               /// <summary>
+               ///   Concatenate the ILists `first' and `second' to a new MemberList.
+               /// </summary>
+               public MemberList (IList first, IList second)
+               {
+                       ArrayList list = new ArrayList ();
+                       list.AddRange (first);
+                       list.AddRange (second);
+                       count = list.Count;
+                       List = list;
+               }
+
+               public static readonly MemberList Empty = new MemberList (new ArrayList ());
+
+               /// <summary>
+               ///   Cast the MemberList into a MemberInfo[] array.
+               /// </summary>
+               /// <remarks>
+               ///   This is an expensive operation, only use it if it's really necessary.
+               /// </remarks>
+               public static explicit operator MemberInfo [] (MemberList list)
+               {
+                       Timer.StartTimer (TimerType.MiscTimer);
+                       MemberInfo [] result = new MemberInfo [list.Count];
+                       list.CopyTo (result, 0);
+                       Timer.StopTimer (TimerType.MiscTimer);
+                       return result;
+               }
+
+               // ICollection
+
+               public int Count {
+                       get {
+                               return count;
+                       }
+               }
+
+               public bool IsSynchronized {
+                       get {
+                               return List.IsSynchronized;
+                       }
+               }
+
+               public object SyncRoot {
+                       get {
+                               return List.SyncRoot;
+                       }
+               }
+
+               public void CopyTo (Array array, int index)
+               {
+                       List.CopyTo (array, index);
+               }
+
+               // IEnumerable
+
+               public IEnumerator GetEnumerator ()
+               {
+                       return List.GetEnumerator ();
+               }
+
+               // IList
+
+               public bool IsFixedSize {
+                       get {
+                               return true;
+                       }
+               }
+
+               public bool IsReadOnly {
+                       get {
+                               return true;
+                       }
+               }
+
+               object IList.this [int index] {
+                       get {
+                               return List [index];
+                       }
+
+                       set {
+                               throw new NotSupportedException ();
+                       }
+               }
+
+               // FIXME: try to find out whether we can avoid the cast in this indexer.
+               public MemberInfo this [int index] {
+                       get {
+                               return (MemberInfo) List [index];
+                       }
+               }
+
+               public int Add (object value)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public void Clear ()
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public bool Contains (object value)
+               {
+                       return List.Contains (value);
+               }
+
+               public int IndexOf (object value)
+               {
+                       return List.IndexOf (value);
+               }
+
+               public void Insert (int index, object value)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public void Remove (object value)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public void RemoveAt (int index)
+               {
+                       throw new NotSupportedException ();
+               }
+       }
+
+       /// <summary>
+       ///   This interface is used to get all members of a class when creating the
+       ///   member cache.  It must be implemented by all DeclSpace derivatives which
+       ///   want to support the member cache and by TypeHandle to get caching of
+       ///   non-dynamic types.
+       /// </summary>
+       public interface IMemberContainer {
+               /// <summary>
+               ///   The name of the IMemberContainer.  This is only used for
+               ///   debugging purposes.
+               /// </summary>
+               string Name {
+                       get;
+               }
+
+               /// <summary>
+               ///   The type of this IMemberContainer.
+               /// </summary>
+               Type Type {
+                       get;
+               }
+
+               /// <summary>
+               ///   Returns the IMemberContainer of the parent class or null if this
+               ///   is an interface or TypeManger.object_type.
+               ///   This is used when creating the member cache for a class to get all
+               ///   members from the parent class.
+               /// </summary>
+               MemberCache ParentCache {
+                       get;
+               }
+
+               /// <summary>
+               ///   Whether this is an interface.
+               /// </summary>
+               bool IsInterface {
+                       get;
+               }
+
+               /// <summary>
+               ///   Returns all members of this class with the corresponding MemberTypes
+               ///   and BindingFlags.
+               /// </summary>
+               /// <remarks>
+               ///   When implementing this method, make sure not to return any inherited
+               ///   members and check the MemberTypes and BindingFlags properly.
+               ///   Unfortunately, System.Reflection is lame and doesn't provide a way to
+               ///   get the BindingFlags (static/non-static,public/non-public) in the
+               ///   MemberInfo class, but the cache needs this information.  That's why
+               ///   this method is called multiple times with different BindingFlags.
+               /// </remarks>
+               MemberList GetMembers (MemberTypes mt, BindingFlags bf);
+
+               /// <summary>
+               ///   Return the container's member cache.
+               /// </summary>
+               MemberCache MemberCache {
+                       get;
+               }
+       }
+
+       /// <summary>
+       ///   The MemberCache is used by dynamic and non-dynamic types to speed up
+       ///   member lookups.  It has a member name based hash table; it maps each member
+       ///   name to a list of CacheEntry objects.  Each CacheEntry contains a MemberInfo
+       ///   and the BindingFlags that were initially used to get it.  The cache contains
+       ///   all members of the current class and all inherited members.  If this cache is
+       ///   for an interface types, it also contains all inherited members.
+       ///
+       ///   There are two ways to get a MemberCache:
+       ///   * if this is a dynamic type, lookup the corresponding DeclSpace and then
+       ///     use the DeclSpace.MemberCache property.
+       ///   * if this not a dynamic type, call TypeHandle.GetTypeHandle() to get a
+       ///     TypeHandle instance for the type and then use TypeHandle.MemberCache.
+       /// </summary>
+       public class MemberCache {
+               public readonly IMemberContainer Container;
+               protected Hashtable member_hash;
+               protected Hashtable method_hash;
+
+               /// <summary>
+               ///   Create a new MemberCache for the given IMemberContainer `container'.
+               /// </summary>
+               public MemberCache (IMemberContainer container)
+               {
+                       this.Container = container;
+
+                       Timer.IncrementCounter (CounterType.MemberCache);
+                       Timer.StartTimer (TimerType.CacheInit);
+
+                       // If we have a parent class (we have a parent class unless we're
+                       // TypeManager.object_type), we deep-copy its MemberCache here.
+                       if (Container.ParentCache != null)
+                               member_hash = SetupCache (Container.ParentCache);
+                       else
+                               member_hash = new Hashtable ();
+
+                       // If this is neither a dynamic type nor an interface, create a special
+                       // method cache with all declared and inherited methods.
+                       Type type = container.Type;
+                       if (!(type is TypeBuilder) && !type.IsInterface && !type.IsGenericParameter) {
+                               method_hash = new Hashtable ();
+                               AddMethods (type);
+                       }
+
+                       // Add all members from the current class.
+                       AddMembers (Container);
+
+                       Timer.StopTimer (TimerType.CacheInit);
+               }
+
+               public MemberCache (Type[] ifaces)
+               {
+                       //
+                       // The members of this cache all belong to other caches.  
+                       // So, 'Container' will not be used.
+                       //
+                       this.Container = null;
+
+                       member_hash = new Hashtable ();
+                       if (ifaces == null)
+                               return;
+
+                       foreach (Type itype in ifaces)
+                               AddCacheContents (TypeManager.LookupMemberCache (itype));
+               }
+
+               /// <summary>
+               ///   Bootstrap this member cache by doing a deep-copy of our parent.
+               /// </summary>
+               Hashtable SetupCache (MemberCache parent)
+               {
+                       Hashtable hash = new Hashtable ();
+
+                       if (parent == null)
+                               return hash;
+
+                       IDictionaryEnumerator it = parent.member_hash.GetEnumerator ();
+                       while (it.MoveNext ()) {
+                               hash [it.Key] = ((ArrayList) it.Value).Clone ();
+                        }
+                                
+                       return hash;
+               }
+
+               /// <summary>
+               ///   Add the contents of `cache' to the member_hash.
+               /// </summary>
+               void AddCacheContents (MemberCache cache)
+               {
+                       IDictionaryEnumerator it = cache.member_hash.GetEnumerator ();
+                       while (it.MoveNext ()) {
+                               ArrayList list = (ArrayList) member_hash [it.Key];
+                               if (list == null)
+                                       member_hash [it.Key] = list = new ArrayList ();
+
+                               ArrayList entries = (ArrayList) it.Value;
+                               for (int i = entries.Count-1; i >= 0; i--) {
+                                       CacheEntry entry = (CacheEntry) entries [i];
+
+                                       if (entry.Container != cache.Container)
+                                               break;
+                                       list.Add (entry);
+                               }
+                       }
+               }
+
+               /// <summary>
+               ///   Add all members from class `container' to the cache.
+               /// </summary>
+               void AddMembers (IMemberContainer container)
+               {
+                       // We need to call AddMembers() with a single member type at a time
+                       // to get the member type part of CacheEntry.EntryType right.
+                       if (!container.IsInterface) {
+                       AddMembers (MemberTypes.Constructor, container);
+                       AddMembers (MemberTypes.Field, container);
+                       }
+                       AddMembers (MemberTypes.Method, container);
+                       AddMembers (MemberTypes.Property, container);
+                       AddMembers (MemberTypes.Event, container);
+                       // Nested types are returned by both Static and Instance searches.
+                       AddMembers (MemberTypes.NestedType,
+                                   BindingFlags.Static | BindingFlags.Public, container);
+                       AddMembers (MemberTypes.NestedType,
+                                   BindingFlags.Static | BindingFlags.NonPublic, container);
+               }
+
+               void AddMembers (MemberTypes mt, IMemberContainer container)
+               {
+                       AddMembers (mt, BindingFlags.Static | BindingFlags.Public, container);
+                       AddMembers (mt, BindingFlags.Static | BindingFlags.NonPublic, container);
+                       AddMembers (mt, BindingFlags.Instance | BindingFlags.Public, container);
+                       AddMembers (mt, BindingFlags.Instance | BindingFlags.NonPublic, container);
+               }
+
+               /// <summary>
+               ///   Add all members from class `container' with the requested MemberTypes and
+               ///   BindingFlags to the cache.  This method is called multiple times with different
+               ///   MemberTypes and BindingFlags.
+               /// </summary>
+               void AddMembers (MemberTypes mt, BindingFlags bf, IMemberContainer container)
+               {
+                       MemberList members = container.GetMembers (mt, bf);
+
+                       foreach (MemberInfo member in members) {
+                               string name = member.Name;
+
+                               int pos = name.IndexOf ('<');
+                               if (pos > 0)
+                                       name = name.Substring (0, pos);
+
+                               // We use a name-based hash table of ArrayList's.
+                               ArrayList list = (ArrayList) member_hash [name];
+                               if (list == null) {
+                                       list = new ArrayList ();
+                                       member_hash.Add (name, list);
+                               }
+
+                               // When this method is called for the current class, the list will
+                               // already contain all inherited members from our parent classes.
+                               // We cannot add new members in front of the list since this'd be an
+                               // expensive operation, that's why the list is sorted in reverse order
+                               // (ie. members from the current class are coming last).
+                               list.Add (new CacheEntry (container, member, mt, bf));
+                       }
+               }
+
+               /// <summary>
+               ///   Add all declared and inherited methods from class `type' to the method cache.
+               /// </summary>
+               void AddMethods (Type type)
+               {
+                       AddMethods (BindingFlags.Static | BindingFlags.Public |
+                                   BindingFlags.FlattenHierarchy, type);
+                       AddMethods (BindingFlags.Static | BindingFlags.NonPublic |
+                                   BindingFlags.FlattenHierarchy, type);
+                       AddMethods (BindingFlags.Instance | BindingFlags.Public, type);
+                       AddMethods (BindingFlags.Instance | BindingFlags.NonPublic, type);
+               }
+
+               void AddMethods (BindingFlags bf, Type type)
+               {
+                       MemberInfo [] members = type.GetMethods (bf);
+
+                       Array.Reverse (members);
+
+                       foreach (MethodBase member in members) {
+                               string name = member.Name;
+
+                               // We use a name-based hash table of ArrayList's.
+                               ArrayList list = (ArrayList) method_hash [name];
+                               if (list == null) {
+                                       list = new ArrayList ();
+                                       method_hash.Add (name, list);
+                               }
+
+                               // Unfortunately, the elements returned by Type.GetMethods() aren't
+                               // sorted so we need to do this check for every member.
+                               BindingFlags new_bf = bf;
+                               if (member.DeclaringType == type)
+                                       new_bf |= BindingFlags.DeclaredOnly;
+
+                               list.Add (new CacheEntry (Container, member, MemberTypes.Method, new_bf));
+                       }
+               }
+
+               /// <summary>
+               ///   Compute and return a appropriate `EntryType' magic number for the given
+               ///   MemberTypes and BindingFlags.
+               /// </summary>
+               protected static EntryType GetEntryType (MemberTypes mt, BindingFlags bf)
+               {
+                       EntryType type = EntryType.None;
+
+                       if ((mt & MemberTypes.Constructor) != 0)
+                               type |= EntryType.Constructor;
+                       if ((mt & MemberTypes.Event) != 0)
+                               type |= EntryType.Event;
+                       if ((mt & MemberTypes.Field) != 0)
+                               type |= EntryType.Field;
+                       if ((mt & MemberTypes.Method) != 0)
+                               type |= EntryType.Method;
+                       if ((mt & MemberTypes.Property) != 0)
+                               type |= EntryType.Property;
+                       // Nested types are returned by static and instance searches.
+                       if ((mt & MemberTypes.NestedType) != 0)
+                               type |= EntryType.NestedType | EntryType.Static | EntryType.Instance;
+
+                       if ((bf & BindingFlags.Instance) != 0)
+                               type |= EntryType.Instance;
+                       if ((bf & BindingFlags.Static) != 0)
+                               type |= EntryType.Static;
+                       if ((bf & BindingFlags.Public) != 0)
+                               type |= EntryType.Public;
+                       if ((bf & BindingFlags.NonPublic) != 0)
+                               type |= EntryType.NonPublic;
+                       if ((bf & BindingFlags.DeclaredOnly) != 0)
+                               type |= EntryType.Declared;
+
+                       return type;
+               }
+
+               /// <summary>
+               ///   The `MemberTypes' enumeration type is a [Flags] type which means that it may
+               ///   denote multiple member types.  Returns true if the given flags value denotes a
+               ///   single member types.
+               /// </summary>
+               public static bool IsSingleMemberType (MemberTypes mt)
+               {
+                       switch (mt) {
+                       case MemberTypes.Constructor:
+                       case MemberTypes.Event:
+                       case MemberTypes.Field:
+                       case MemberTypes.Method:
+                       case MemberTypes.Property:
+                       case MemberTypes.NestedType:
+                               return true;
+
+                       default:
+                               return false;
+                       }
+               }
+
+               /// <summary>
+               ///   We encode the MemberTypes and BindingFlags of each members in a "magic"
+               ///   number to speed up the searching process.
+               /// </summary>
+               [Flags]
+               protected enum EntryType {
+                       None            = 0x000,
+
+                       Instance        = 0x001,
+                       Static          = 0x002,
+                       MaskStatic      = Instance|Static,
+
+                       Public          = 0x004,
+                       NonPublic       = 0x008,
+                       MaskProtection  = Public|NonPublic,
+
+                       Declared        = 0x010,
+
+                       Constructor     = 0x020,
+                       Event           = 0x040,
+                       Field           = 0x080,
+                       Method          = 0x100,
+                       Property        = 0x200,
+                       NestedType      = 0x400,
+
+                       MaskType        = Constructor|Event|Field|Method|Property|NestedType
+               }
+
+               protected struct CacheEntry {
+                       public readonly IMemberContainer Container;
+                       public readonly EntryType EntryType;
+                       public readonly MemberInfo Member;
+
+                       public CacheEntry (IMemberContainer container, MemberInfo member,
+                                          MemberTypes mt, BindingFlags bf)
+                       {
+                               this.Container = container;
+                               this.Member = member;
+                               this.EntryType = GetEntryType (mt, bf);
+                       }
+
+                       public override string ToString ()
+                       {
+                               return String.Format ("CacheEntry ({0}:{1}:{2})", Container.Name,
+                                                     EntryType, Member);
+                       }
+               }
+
+               /// <summary>
+               ///   This is called each time we're walking up one level in the class hierarchy
+               ///   and checks whether we can abort the search since we've already found what
+               ///   we were looking for.
+               /// </summary>
+               protected bool DoneSearching (ArrayList list)
+               {
+                       //
+                       // We've found exactly one member in the current class and it's not
+                       // a method or constructor.
+                       //
+                       if (list.Count == 1 && !(list [0] is MethodBase))
+                               return true;
+
+                       //
+                       // Multiple properties: we query those just to find out the indexer
+                       // name
+                       //
+                       if ((list.Count > 0) && (list [0] is PropertyInfo))
+                               return true;
+
+                       return false;
+               }
+
+               /// <summary>
+               ///   Looks up members with name `name'.  If you provide an optional
+               ///   filter function, it'll only be called with members matching the
+               ///   requested member name.
+               ///
+               ///   This method will try to use the cache to do the lookup if possible.
+               ///
+               ///   Unlike other FindMembers implementations, this method will always
+               ///   check all inherited members - even when called on an interface type.
+               ///
+               ///   If you know that you're only looking for methods, you should use
+               ///   MemberTypes.Method alone since this speeds up the lookup a bit.
+               ///   When doing a method-only search, it'll try to use a special method
+               ///   cache (unless it's a dynamic type or an interface) and the returned
+               ///   MemberInfo's will have the correct ReflectedType for inherited methods.
+               ///   The lookup process will automatically restart itself in method-only
+               ///   search mode if it discovers that it's about to return methods.
+               /// </summary>
+               ArrayList global = new ArrayList ();
+               bool using_global = false;
+               
+               static MemberInfo [] emptyMemberInfo = new MemberInfo [0];
+               
+               public MemberInfo [] FindMembers (MemberTypes mt, BindingFlags bf, string name,
+                                              MemberFilter filter, object criteria)
+               {
+                       if (using_global)
+                               throw new Exception ();
+                       
+                       bool declared_only = (bf & BindingFlags.DeclaredOnly) != 0;
+                       bool method_search = mt == MemberTypes.Method;
+                       // If we have a method cache and we aren't already doing a method-only search,
+                       // then we restart a method search if the first match is a method.
+                       bool do_method_search = !method_search && (method_hash != null);
+
+                       ArrayList applicable;
+
+                       // If this is a method-only search, we try to use the method cache if
+                       // possible; a lookup in the method cache will return a MemberInfo with
+                       // the correct ReflectedType for inherited methods.
+                       
+                       if (method_search && (method_hash != null))
+                               applicable = (ArrayList) method_hash [name];
+                       else
+                               applicable = (ArrayList) member_hash [name];
+
+                       if (applicable == null)
+                               return emptyMemberInfo;
+
+                       //
+                       // 32  slots gives 53 rss/54 size
+                       // 2/4 slots gives 55 rss
+                       //
+                       // Strange: from 25,000 calls, only 1,800
+                       // are above 2.  Why does this impact it?
+                       //
+                       global.Clear ();
+                       using_global = true;
+
+                       Timer.StartTimer (TimerType.CachedLookup);
+
+                       EntryType type = GetEntryType (mt, bf);
+
+                       IMemberContainer current = Container;
+
+
+                       // `applicable' is a list of all members with the given member name `name'
+                       // in the current class and all its parent classes.  The list is sorted in
+                       // reverse order due to the way how the cache is initialy created (to speed
+                       // things up, we're doing a deep-copy of our parent).
+
+                       for (int i = applicable.Count-1; i >= 0; i--) {
+                               CacheEntry entry = (CacheEntry) applicable [i];
+
+                               // This happens each time we're walking one level up in the class
+                               // hierarchy.  If we're doing a DeclaredOnly search, we must abort
+                               // the first time this happens (this may already happen in the first
+                               // iteration of this loop if there are no members with the name we're
+                               // looking for in the current class).
+                               if (entry.Container != current) {
+                                       if (declared_only || DoneSearching (global))
+                                               break;
+
+                                       current = entry.Container;
+                               }
+
+                               // Is the member of the correct type ?
+                               if ((entry.EntryType & type & EntryType.MaskType) == 0)
+                                       continue;
+
+                               // Is the member static/non-static ?
+                               if ((entry.EntryType & type & EntryType.MaskStatic) == 0)
+                                       continue;
+
+                               // Apply the filter to it.
+                               if (filter (entry.Member, criteria)) {
+                                       if ((entry.EntryType & EntryType.MaskType) != EntryType.Method)
+                                               do_method_search = false;
+                                       global.Add (entry.Member);
+                               }
+                       }
+
+                       Timer.StopTimer (TimerType.CachedLookup);
+
+                       // If we have a method cache and we aren't already doing a method-only
+                       // search, we restart in method-only search mode if the first match is
+                       // a method.  This ensures that we return a MemberInfo with the correct
+                       // ReflectedType for inherited methods.
+                       if (do_method_search && (global.Count > 0)){
+                               using_global = false;
+
+                               return FindMembers (MemberTypes.Method, bf, name, filter, criteria);
+                       }
+
+                       using_global = false;
+                       MemberInfo [] copy = new MemberInfo [global.Count];
+                       global.CopyTo (copy);
+                       return copy;
+               }
+               
+               //
+               // This finds the method or property for us to override. invocationType is the type where
+               // the override is going to be declared, name is the name of the method/property, and
+               // paramTypes is the parameters, if any to the method or property
+               //
+               // Because the MemberCache holds members from this class and all the base classes,
+               // we can avoid tons of reflection stuff.
+               //
+               public MemberInfo FindMemberToOverride (Type invocationType, string name, Type [] paramTypes, bool is_property)
+               {
+                       ArrayList applicable;
+                       if (method_hash != null && !is_property)
+                               applicable = (ArrayList) method_hash [name];
+                       else
+                               applicable = (ArrayList) member_hash [name];
+                       
+                       if (applicable == null)
+                               return null;
+                       //
+                       // Walk the chain of methods, starting from the top.
+                       //
+                       for (int i = applicable.Count - 1; i >= 0; i--) {
+                               CacheEntry entry = (CacheEntry) applicable [i];
+                               
+                               if ((entry.EntryType & (is_property ? (EntryType.Property | EntryType.Field) : EntryType.Method)) == 0)
+                                       continue;
+
+                               PropertyInfo pi = null;
+                               MethodInfo mi = null;
+                               FieldInfo fi = null;
+                               Type [] cmpAttrs = null;
+                               
+                               if (is_property) {
+                                       if ((entry.EntryType & EntryType.Field) != 0) {
+                                               fi = (FieldInfo)entry.Member;
+
+                                               // TODO: For this case we ignore member type
+                                               //fb = TypeManager.GetField (fi);
+                                               //cmpAttrs = new Type[] { fb.MemberType };
+                                       } else {
+                                               pi = (PropertyInfo) entry.Member;
+                                               cmpAttrs = TypeManager.GetArgumentTypes (pi);
+                                       }
+                               } else {
+                                       mi = (MethodInfo) entry.Member;
+                                       cmpAttrs = TypeManager.GetArgumentTypes (mi);
+                               }
+
+                               if (fi != null) {
+                                       // TODO: Almost duplicate !
+                                       // Check visibility
+                                       switch (fi.Attributes & FieldAttributes.FieldAccessMask) {
+                                               case FieldAttributes.Private:
+                                                       //
+                                                       // A private method is Ok if we are a nested subtype.
+                                                       // The spec actually is not very clear about this, see bug 52458.
+                                                       //
+                                                       if (invocationType != entry.Container.Type &
+                                                               TypeManager.IsNestedChildOf (invocationType, entry.Container.Type))
+                                                               continue;
+
+                                                       break;
+                                               case FieldAttributes.FamANDAssem:
+                                               case FieldAttributes.Assembly:
+                                                       //
+                                                       // Check for assembly methods
+                                                       //
+                                                       if (mi.DeclaringType.Assembly != CodeGen.Assembly.Builder)
+                                                               continue;
+                                                       break;
+                                       }
+                                       return entry.Member;
+                               }
+
+                               //
+                               // Check the arguments
+                               //
+                               if (cmpAttrs.Length != paramTypes.Length)
+                                       continue;
+
+                               for (int j = cmpAttrs.Length - 1; j >= 0; j --) {
+                                       if (!TypeManager.IsEqual (paramTypes [j], cmpAttrs [j]))
+                                               goto next;
+                               }
+                               
+                               //
+                               // get one of the methods because this has the visibility info.
+                               //
+                               if (is_property) {
+                                       mi = pi.GetGetMethod (true);
+                                       if (mi == null)
+                                               mi = pi.GetSetMethod (true);
+                               }
+                               
+                               //
+                               // Check visibility
+                               //
+                               switch (mi.Attributes & MethodAttributes.MemberAccessMask) {
+                               case MethodAttributes.Private:
+                                       //
+                                       // A private method is Ok if we are a nested subtype.
+                                       // The spec actually is not very clear about this, see bug 52458.
+                                       //
+                                       if (invocationType.Equals (entry.Container.Type) ||
+                                           TypeManager.IsNestedChildOf (invocationType, entry.Container.Type))
+                                               return entry.Member;
+                                       
+                                       break;
+                               case MethodAttributes.FamANDAssem:
+                               case MethodAttributes.Assembly:
+                                       //
+                                       // Check for assembly methods
+                                       //
+                                       if (mi.DeclaringType.Assembly == CodeGen.Assembly.Builder)
+                                               return entry.Member;
+                                       
+                                       break;
+                               default:
+                                       //
+                                       // A protected method is ok, because we are overriding.
+                                       // public is always ok.
+                                       //
+                                       return entry.Member;
+                               }
+                       next:
+                               ;
+                       }
+                       
+                       return null;
+               }
+
+               /// <summary>
+               /// The method is looking for conflict with inherited symbols (errors CS0108, CS0109).
+               /// We handle two cases. The first is for types without parameters (events, field, properties).
+               /// The second are methods, indexers and this is why ignore_complex_types is here.
+               /// The latest param is temporary hack. See DoDefineMembers method for more info.
+               /// </summary>
+               public MemberInfo FindMemberWithSameName (string name, bool ignore_complex_types, MemberInfo ignore_member)
+               {
+                       ArrayList applicable = null;
+                       if (method_hash != null)
+                               applicable = (ArrayList) method_hash [name];
+                       if (applicable != null) {
+                               for (int i = applicable.Count - 1; i >= 0; i--) {
+                                       CacheEntry entry = (CacheEntry) applicable [i];
+                                       if ((entry.EntryType & EntryType.Public) != 0)
+                                               return entry.Member;
+                               }
+                       }
+                       if (member_hash == null)
+                               return null;
+                       applicable = (ArrayList) member_hash [name];
+                       
+                       if (applicable != null) {
+                               for (int i = applicable.Count - 1; i >= 0; i--) {
+                                       CacheEntry entry = (CacheEntry) applicable [i];
+                                       if ((entry.EntryType & EntryType.Public) != 0 & entry.Member != ignore_member) {
+                                               if (ignore_complex_types) {
+                                                       if ((entry.EntryType & EntryType.Method) != 0)
+                                                               continue;
+                                                       // Does exist easier way how to detect indexer ?
+                                                       if ((entry.EntryType & EntryType.Property) != 0) {
+                                                               Type[] arg_types = TypeManager.GetArgumentTypes ((PropertyInfo)entry.Member);
+                                                               if (arg_types.Length > 0)
+                                                                       continue;
+                                                       }
+                                               }
+                                               return entry.Member;
+                                       }
+                               }
+                       }
+                       return null;
+               }
+
+               Hashtable locase_table;
+               /// <summary>
+               /// Builds low-case table for CLS Compliance test
+               /// </summary>
+               public Hashtable GetPublicMembers ()
+               {
+                       if (locase_table != null)
+                               return locase_table;
+                       locase_table = new Hashtable ();
+                       foreach (DictionaryEntry entry in member_hash) {
+                               ArrayList members = (ArrayList)entry.Value;
+                               for (int ii = 0; ii < members.Count; ++ii) {
+                                       CacheEntry member_entry = (CacheEntry) members [ii];
+                                       if ((member_entry.EntryType & EntryType.Public) == 0)
+                                               continue;
+                                       // TODO: Does anyone know easier way how to detect that member is internal ?
+                                       switch (member_entry.EntryType & EntryType.MaskType) {
+                                               case EntryType.Constructor:
+                                                       continue;
+                                               case EntryType.Field:
+                                                       if ((((FieldInfo)member_entry.Member).Attributes & (FieldAttributes.Assembly | FieldAttributes.Public)) == FieldAttributes.Assembly)
+                                                               continue;
+                                                       break;
+                                               case EntryType.Method:
+                                                       if ((((MethodInfo)member_entry.Member).Attributes & (MethodAttributes.Assembly | MethodAttributes.Public)) == MethodAttributes.Assembly)
+                                                               continue;
+                                                       break;
+                                               case EntryType.Property:
+                                                       PropertyInfo pi = (PropertyInfo)member_entry.Member;
+                                                       if (pi.GetSetMethod () == null && pi.GetGetMethod () == null)
+                                                               continue;
+                                                       break;
+                                               case EntryType.Event:
+                                                       EventInfo ei = (EventInfo)member_entry.Member;
+                                                       MethodInfo mi = ei.GetAddMethod ();
+                                                       if ((mi.Attributes & (MethodAttributes.Assembly | MethodAttributes.Public)) == MethodAttributes.Assembly)
+                                                               continue;
+                                                       break;
+                                       }
+                                       string lcase = ((string)entry.Key).ToLower (System.Globalization.CultureInfo.InvariantCulture);
+                                       locase_table [lcase] = member_entry.Member;
+                                       break;
+                               }
+                       }
+                       return locase_table;
+               }
+               public Hashtable Members {
+                       get {
+                               return member_hash;
+                       }
+               }
+               /// <summary>
+               /// Cls compliance check whether methods or constructors parameters differing only in ref or out, or in array rank
+               /// </summary>
+               public void VerifyClsParameterConflict (ArrayList al, MethodCore method, MemberInfo this_builder)
+               {
+                       EntryType tested_type = (method is Constructor ? EntryType.Constructor : EntryType.Method) | EntryType.Public;
+                       for (int i = 0; i < al.Count; ++i) {
+                               MemberCache.CacheEntry entry = (MemberCache.CacheEntry) al [i];
+               
+                               // skip itself
+                               if (entry.Member == this_builder)
+                                       continue;
+               
+                               if ((entry.EntryType & tested_type) != tested_type)
+                                       continue;
+               
+                               MethodBase method_to_compare = (MethodBase)entry.Member;
+                               if (AttributeTester.AreOverloadedMethodParamsClsCompliant (method.ParameterTypes, TypeManager.GetArgumentTypes (method_to_compare)))
+                                       continue;
+
+                               IMethodData md = TypeManager.GetMethod (method_to_compare);
+
+                               // TODO: now we are ignoring CLSCompliance(false) on method from other assembly which is buggy.
+                               // However it is exactly what csc does.
+                               if (md != null && !md.IsClsCompliaceRequired (method.Parent))
+                                       continue;
+               
+                               Report.SymbolRelatedToPreviousError (entry.Member);
+                               Report.Error (3006, method.Location, "Overloaded method '{0}' differing only in ref or out, or in array rank, is not CLS-compliant", method.GetSignatureForError ());
+                       }
+               }
+       }
+}
diff --git a/mcs/bmcs/delegate.cs b/mcs/bmcs/delegate.cs
new file mode 100644 (file)
index 0000000..5e304f9
--- /dev/null
@@ -0,0 +1,1048 @@
+//
+// delegate.cs: Delegate Handler
+//
+// Authors:
+//     Ravi Pratap (ravi@ximian.com)
+//     Miguel de Icaza (miguel@ximian.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+//
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+
+namespace Mono.CSharp {
+
+       /// <summary>
+       ///   Holds Delegates
+       /// </summary>
+       public class Delegate : DeclSpace {
+               public Expression ReturnType;
+               public Parameters      Parameters;
+
+               public ConstructorBuilder ConstructorBuilder;
+               public MethodBuilder      InvokeBuilder;
+               public MethodBuilder      BeginInvokeBuilder;
+               public MethodBuilder      EndInvokeBuilder;
+               
+               Type [] param_types;
+               Type ret_type;
+
+               static string[] attribute_targets = new string [] { "type", "return" };
+               
+               Expression instance_expr;
+               MethodBase delegate_method;
+               ReturnParameter return_attributes;
+       
+               const int AllowedModifiers =
+                       Modifiers.NEW |
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.UNSAFE |
+                       Modifiers.PRIVATE;
+
+               public Delegate (NamespaceEntry ns, TypeContainer parent, Expression type,
+                                int mod_flags, MemberName name, Parameters param_list,
+                                Attributes attrs, Location l)
+                       : base (ns, parent, name, attrs, l)
+
+               {
+                       this.ReturnType = type;
+                       ModFlags        = Modifiers.Check (AllowedModifiers, mod_flags,
+                                                          IsTopLevel ? Modifiers.INTERNAL :
+                                                          Modifiers.PRIVATE, l);
+                       Parameters      = param_list;
+               }
+
+               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Target == AttributeTargets.ReturnValue) {
+                               if (return_attributes == null)
+                                       return_attributes = new ReturnParameter (InvokeBuilder, Location);
+
+                               return_attributes.ApplyAttributeBuilder (a, cb);
+                               return;
+                       }
+
+                       base.ApplyAttributeBuilder (a, cb);
+               }
+
+               public override TypeBuilder DefineType ()
+               {
+                       if (TypeBuilder != null)
+                               return TypeBuilder;
+
+                       ec = new EmitContext (this, this, Location, null, null, ModFlags, false);
+
+                       if (IsGeneric) {
+                               foreach (TypeParameter type_param in TypeParameters)
+                                       if (!type_param.Resolve (this))
+                                               return null;
+                       }
+                       
+                       TypeAttributes attr = Modifiers.TypeAttr (ModFlags, IsTopLevel) |
+                               TypeAttributes.Class | TypeAttributes.Sealed;
+
+                       if (IsTopLevel) {
+                               if (TypeManager.NamespaceClash (Name, Location))
+                                       return null;
+                               
+                               ModuleBuilder builder = CodeGen.Module.Builder;
+
+                               TypeBuilder = builder.DefineType (
+                                       Name, attr, TypeManager.multicast_delegate_type);
+                       } else {
+                               TypeBuilder builder = Parent.TypeBuilder;
+
+                               string name = Name.Substring (1 + Name.LastIndexOf ('.'));
+                               TypeBuilder = builder.DefineNestedType (
+                                       name, attr, TypeManager.multicast_delegate_type);
+                       }
+
+                       TypeManager.AddDelegateType (Name, TypeBuilder, this);
+
+                       if (IsGeneric) {
+                               string[] param_names = new string [TypeParameters.Length];
+                               for (int i = 0; i < TypeParameters.Length; i++)
+                                       param_names [i] = TypeParameters [i].Name;
+
+                               GenericTypeParameterBuilder[] gen_params;
+                               
+                               gen_params = TypeBuilder.DefineGenericParameters (param_names);
+
+                               for (int i = 0; i < gen_params.Length; i++)
+                                       TypeParameters [i].Define (gen_params [i]);
+
+                               foreach (TypeParameter type_param in TypeParameters) {
+                                       if (!type_param.DefineType (ec))
+                                               return null;
+                               }
+
+                               TypeExpr current = new ConstructedType (Name, TypeParameters, Location);
+                               current = current.ResolveAsTypeTerminal (ec);
+                               if (current == null)
+                                       return null;
+
+                               CurrentType = current.Type;
+                       }
+
+                       return TypeBuilder;
+               }
+
+               public override bool DefineMembers (TypeContainer container)
+               {
+                       return true;
+               }
+
+               public override bool Define ()
+               {
+                       MethodAttributes mattr;
+                       int i;
+                       ec = new EmitContext (this, this, Location, null, null, ModFlags, false);
+
+                       if (IsGeneric) {
+                               foreach (TypeParameter type_param in TypeParameters)
+                                       type_param.DefineType (ec);
+                       }
+
+                       // FIXME: POSSIBLY make this static, as it is always constant
+                       //
+                       Type [] const_arg_types = new Type [2];
+                       const_arg_types [0] = TypeManager.object_type;
+                       const_arg_types [1] = TypeManager.intptr_type;
+
+                       mattr = MethodAttributes.RTSpecialName | MethodAttributes.SpecialName |
+                               MethodAttributes.HideBySig | MethodAttributes.Public;
+
+                       ConstructorBuilder = TypeBuilder.DefineConstructor (mattr,
+                                                                           CallingConventions.Standard,
+                                                                           const_arg_types);
+
+                       ConstructorBuilder.DefineParameter (1, ParameterAttributes.None, "object");
+                       ConstructorBuilder.DefineParameter (2, ParameterAttributes.None, "method");
+                       //
+                       // HACK because System.Reflection.Emit is lame
+                       //
+                       //
+                       // FIXME: POSSIBLY make these static, as they are always the same
+                       Parameter [] fixed_pars = new Parameter [2];
+                       fixed_pars [0] = new Parameter (TypeManager.system_object_expr, "object",
+                                                       Parameter.Modifier.NONE, null);
+                       fixed_pars [1] = new Parameter (TypeManager.system_intptr_expr, "method", 
+                                                       Parameter.Modifier.NONE, null);
+                       Parameters const_parameters = new Parameters (fixed_pars, null, Location);
+                       
+                       TypeManager.RegisterMethod (
+                               ConstructorBuilder,
+                               new InternalParameters (const_arg_types, const_parameters),
+                               const_arg_types);
+                               
+                       
+                       ConstructorBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
+
+                       //
+                       // Here the various methods like Invoke, BeginInvoke etc are defined
+                       //
+                       // First, call the `out of band' special method for
+                       // defining recursively any types we need:
+                       
+                       if (!Parameters.ComputeAndDefineParameterTypes (ec))
+                               return false;
+                       
+                       param_types = Parameters.GetParameterInfo (ec);
+                       if (param_types == null)
+                               return false;
+
+                       //
+                       // Invoke method
+                       //
+
+                       // Check accessibility
+                       foreach (Type partype in param_types){
+                               if (!Parent.AsAccessible (partype, ModFlags)) {
+                                       Report.Error (59, Location,
+                                                     "Inconsistent accessibility: parameter type `" +
+                                                     TypeManager.CSharpName (partype) + "` is less " +
+                                                     "accessible than delegate `" + Name + "'");
+                                       return false;
+                               }
+                               if (partype.IsPointer && !UnsafeOK (Parent))
+                                       return false;
+                       }
+                       
+                       ReturnType = ReturnType.ResolveAsTypeTerminal (ec);
+                        if (ReturnType == null)
+                            return false;
+                        
+                       ret_type = ReturnType.Type;
+                       if (ret_type == null)
+                               return false;
+
+                       if (!Parent.AsAccessible (ret_type, ModFlags)) {
+                               Report.Error (58, Location,
+                                             "Inconsistent accessibility: return type `" +
+                                             TypeManager.CSharpName (ret_type) + "` is less " +
+                                             "accessible than delegate `" + Name + "'");
+                               return false;
+                       }
+
+                       if (ret_type.IsPointer && !UnsafeOK (Parent))
+                               return false;
+
+                       //
+                       // We don't have to check any others because they are all
+                       // guaranteed to be accessible - they are standard types.
+                       //
+                       
+                       CallingConventions cc = Parameters.GetCallingConvention ();
+
+                       mattr = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Virtual;
+
+                       InvokeBuilder = TypeBuilder.DefineMethod ("Invoke", 
+                                                                 mattr,                     
+                                                                 cc,
+                                                                 ret_type,                  
+                                                                 param_types);
+
+                       //
+                       // Define parameters, and count out/ref parameters
+                       //
+                       int out_params = 0;
+                       i = 0;
+                       if (Parameters.FixedParameters != null){
+                               int top = Parameters.FixedParameters.Length;
+                               Parameter p;
+                               
+                               for (; i < top; i++) {
+                                       p = Parameters.FixedParameters [i];
+                                       p.DefineParameter (ec, InvokeBuilder, null, i + 1, Location);
+
+                                       if ((p.ModFlags & Parameter.Modifier.ISBYREF) != 0)
+                                               out_params++;
+                               }
+                       }
+                       if (Parameters.ArrayParameter != null){
+                               Parameter p = Parameters.ArrayParameter;
+                               p.DefineParameter (ec, InvokeBuilder, null, i + 1, Location);
+                       }
+                       
+                       InvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
+
+                       TypeManager.RegisterMethod (InvokeBuilder,
+                                                   new InternalParameters (param_types, Parameters),
+                                                   param_types);
+
+                       //
+                       // BeginInvoke
+                       //
+                       int params_num = param_types.Length;
+                       Type [] async_param_types = new Type [params_num + 2];
+
+                       param_types.CopyTo (async_param_types, 0);
+
+                       async_param_types [params_num] = TypeManager.asynccallback_type;
+                       async_param_types [params_num + 1] = TypeManager.object_type;
+
+                       mattr = MethodAttributes.Public | MethodAttributes.HideBySig |
+                               MethodAttributes.Virtual | MethodAttributes.NewSlot;
+                       
+                       BeginInvokeBuilder = TypeBuilder.DefineMethod ("BeginInvoke",
+                                                                      mattr,
+                                                                      cc,
+                                                                      TypeManager.iasyncresult_type,
+                                                                      async_param_types);
+
+                       i = 0;
+                       if (Parameters.FixedParameters != null){
+                               int top = Parameters.FixedParameters.Length;
+                               Parameter p;
+                               
+                               for (i = 0 ; i < top; i++) {
+                                       p = Parameters.FixedParameters [i];
+
+                                       p.DefineParameter (ec, BeginInvokeBuilder, null, i + 1, Location);
+                               }
+                       }
+                       if (Parameters.ArrayParameter != null){
+                               Parameter p = Parameters.ArrayParameter;
+                               p.DefineParameter (ec, BeginInvokeBuilder, null, i + 1, Location);
+
+                               i++;
+                       }
+
+                       BeginInvokeBuilder.DefineParameter (i + 1, ParameterAttributes.None, "callback");
+                       BeginInvokeBuilder.DefineParameter (i + 2, ParameterAttributes.None, "object");
+                       
+                       BeginInvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
+
+                       Parameter [] async_params = new Parameter [params_num + 2];
+                       int n = 0;
+                       if (Parameters.FixedParameters != null){
+                               Parameters.FixedParameters.CopyTo (async_params, 0);
+                               n = Parameters.FixedParameters.Length;
+                       }
+                       if (Parameters.ArrayParameter != null)
+                               async_params [n] = Parameters.ArrayParameter;
+                       
+                       async_params [params_num] = new Parameter (
+                               TypeManager.system_asynccallback_expr, "callback",
+                                                                  Parameter.Modifier.NONE, null);
+                       async_params [params_num + 1] = new Parameter (
+                               TypeManager.system_object_expr, "object",
+                                                                  Parameter.Modifier.NONE, null);
+
+                       Parameters async_parameters = new Parameters (async_params, null, Location);
+                       async_parameters.ComputeAndDefineParameterTypes (ec);
+                       
+                       TypeManager.RegisterMethod (BeginInvokeBuilder,
+                                                   new InternalParameters (async_param_types, async_parameters),
+                                                   async_param_types);
+
+                       //
+                       // EndInvoke is a bit more interesting, all the parameters labeled as
+                       // out or ref have to be duplicated here.
+                       //
+                       
+                       Type [] end_param_types = new Type [out_params + 1];
+                       Parameter [] end_params = new Parameter [out_params + 1];
+                       int param = 0; 
+                       if (out_params > 0){
+                               int top = Parameters.FixedParameters.Length;
+                               for (i = 0; i < top; i++){
+                                       Parameter p = Parameters.FixedParameters [i];
+                                       if ((p.ModFlags & Parameter.Modifier.ISBYREF) == 0)
+                                               continue;
+
+                                       end_param_types [param] = param_types [i];
+                                       end_params [param] = p;
+                                       param++;
+                               }
+                       }
+                       end_param_types [out_params] = TypeManager.iasyncresult_type;
+                       end_params [out_params] = new Parameter (TypeManager.system_iasyncresult_expr, "result", Parameter.Modifier.NONE, null);
+
+                       //
+                       // Create method, define parameters, register parameters with type system
+                       //
+                       EndInvokeBuilder = TypeBuilder.DefineMethod ("EndInvoke", mattr, cc, ret_type, end_param_types);
+                       EndInvokeBuilder.SetImplementationFlags (MethodImplAttributes.Runtime);
+
+                       //
+                       // EndInvoke: Label the parameters
+                       //
+                       EndInvokeBuilder.DefineParameter (out_params + 1, ParameterAttributes.None, "result");
+                       for (i = 0; i < end_params.Length-1; i++){
+                               EndInvokeBuilder.DefineParameter (i + 1, end_params [i].Attributes, end_params [i].Name);
+                       }
+
+                       Parameters end_parameters = new Parameters (end_params, null, Location);
+                       end_parameters.ComputeAndDefineParameterTypes (ec);
+
+                       TypeManager.RegisterMethod (
+                               EndInvokeBuilder,
+                               new InternalParameters (end_param_types, end_parameters),
+                               end_param_types);
+
+                       return true;
+               }
+
+               public override void Emit ()
+               {
+                       if (OptAttributes != null) {
+                               Parameters.LabelParameters (ec, InvokeBuilder, Location);
+                               OptAttributes.Emit (ec, this);
+                       }
+
+                       base.Emit ();
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+
+               //TODO: duplicate
+               protected override bool VerifyClsCompliance (DeclSpace ds)
+               {
+                       if (!base.VerifyClsCompliance (ds)) {
+                               return false;
+                       }
+
+                       AttributeTester.AreParametersCompliant (Parameters.FixedParameters, Location);
+
+                       if (!AttributeTester.IsClsCompliant (ReturnType.Type)) {
+                               Report.Error (3002, Location, "Return type of '{0}' is not CLS-compliant", GetSignatureForError ());
+                       }
+                       return true;
+               }
+
+               //
+               // Returns the MethodBase for "Invoke" from a delegate type, this is used
+               // to extract the signature of a delegate.
+               //
+               public static MethodGroupExpr GetInvokeMethod (EmitContext ec, Type delegate_type,
+                                                      Location loc)
+               {
+                       Expression ml = Expression.MemberLookup (
+                               ec, delegate_type, "Invoke", loc);
+
+                       MethodGroupExpr mg = ml as MethodGroupExpr;
+                       if (mg == null) {
+                               Report.Error (-100, loc, "Internal error: could not find Invoke method!");
+                               return null;
+                       }
+
+                       return mg;
+               }
+               
+               /// <summary>
+               ///  Verifies whether the method in question is compatible with the delegate
+               ///  Returns the method itself if okay and null if not.
+               /// </summary>
+               public static MethodBase VerifyMethod (EmitContext ec, Type delegate_type, MethodBase mb,
+                                                      Location loc)
+               {
+                       MethodGroupExpr mg = GetInvokeMethod (ec, delegate_type, loc);
+                       if (mg == null)
+                               return null;
+
+                       MethodBase invoke_mb = mg.Methods [0];
+                       ParameterData invoke_pd = Invocation.GetParameterData (invoke_mb);
+
+                       if (!mg.HasTypeArguments &&
+                           !TypeManager.InferTypeArguments (ec, invoke_pd, ref mb))
+                               return null;
+
+                       ParameterData pd = Invocation.GetParameterData (mb);
+                       int pd_count = pd.Count;
+
+                       if (invoke_pd.Count != pd_count)
+                               return null;
+
+                       for (int i = pd_count; i > 0; ) {
+                               i--;
+
+                               Type invoke_pd_type = invoke_pd.ParameterType (i);
+                               Type pd_type = pd.ParameterType (i);
+                               Parameter.Modifier invoke_pd_type_mod = invoke_pd.ParameterModifier (i);
+                               Parameter.Modifier pd_type_mod = pd.ParameterModifier (i);
+
+                               if (invoke_pd_type == pd_type &&
+                                   invoke_pd_type_mod == pd_type_mod)
+                                       continue;
+                               
+                               if (invoke_pd_type.IsSubclassOf (pd_type) && 
+                                               invoke_pd_type_mod == pd_type_mod)
+                                       if (RootContext.Version == LanguageVersion.ISO_1) {
+                                               Report.FeatureIsNotStandardized (loc, "contravariance");
+                                               return null;
+                                       } else
+                                               continue;
+                                       
+                               return null;
+                       }
+
+                       Type invoke_mb_retval = ((MethodInfo) invoke_mb).ReturnType;
+                       Type mb_retval = ((MethodInfo) mb).ReturnType;
+                       if (invoke_mb_retval == mb_retval)
+                               return mb;
+                       
+                       if (mb_retval.IsSubclassOf (invoke_mb_retval))
+                               if (RootContext.Version == LanguageVersion.ISO_1) {
+                                       Report.FeatureIsNotStandardized (loc, "covariance");
+                                       return null;
+                               }
+                               else
+                                       return mb;
+                       
+                       return null;
+               }
+
+               // <summary>
+               //  Verifies whether the invocation arguments are compatible with the
+               //  delegate's target method
+               // </summary>
+               public static bool VerifyApplicability (EmitContext ec, Type delegate_type,
+                                                       ArrayList args, Location loc)
+               {
+                       int arg_count;
+
+                       if (args == null)
+                               arg_count = 0;
+                       else
+                               arg_count = args.Count;
+
+                       Expression ml = Expression.MemberLookup (
+                               ec, delegate_type, "Invoke", loc);
+
+                       if (!(ml is MethodGroupExpr)) {
+                               Report.Error (-100, loc, "Internal error: could not find Invoke method!" + delegate_type);
+                               return false;
+                       }
+                       
+                       MethodBase mb = ((MethodGroupExpr) ml).Methods [0];
+                       ParameterData pd = Invocation.GetParameterData (mb);
+
+                       int pd_count = pd.Count;
+
+                       bool params_method = (pd_count != 0) &&
+                               (pd.ParameterModifier (pd_count - 1) == Parameter.Modifier.PARAMS);
+
+                       if (!params_method && pd_count != arg_count) {
+                               Report.Error (1593, loc,
+                                             "Delegate '{0}' does not take {1} arguments",
+                                             delegate_type.ToString (), arg_count);
+                               return false;
+                       }
+
+                       //
+                       // Consider the case:
+                       //   delegate void FOO(param object[] args);
+                       //   FOO f = new FOO(...);
+                       //   f(new object[] {1, 2, 3});
+                       //
+                       // This should be treated like f(1,2,3).  This is done by ignoring the 
+                       // 'param' modifier for that invocation.  If that fails, then the
+                       // 'param' modifier is considered.
+                       //
+                       // One issue is that 'VerifyArgumentsCompat' modifies the elements of
+                       // the 'args' array.  However, the modifications appear idempotent.
+                       // Normal 'Invocation's also have the same behaviour, implicitly.
+                       //
+
+                       bool ans = false;
+                       if (arg_count == pd_count)
+                               ans = Invocation.VerifyArgumentsCompat (
+                                       ec, args, arg_count, mb, false,
+                                       delegate_type, false, loc);
+                       if (!ans && params_method)
+                               ans = Invocation.VerifyArgumentsCompat (
+                                       ec, args, arg_count, mb, true,
+                                       delegate_type, false, loc);
+                       return ans;
+               }
+               
+               /// <summary>
+               ///  Verifies whether the delegate in question is compatible with this one in
+               ///  order to determine if instantiation from the same is possible.
+               /// </summary>
+               public static bool VerifyDelegate (EmitContext ec, Type delegate_type, Type probe_type, Location loc)
+               {
+                       Expression ml = Expression.MemberLookup (
+                               ec, delegate_type, "Invoke", loc);
+                       
+                       if (!(ml is MethodGroupExpr)) {
+                               Report.Error (-100, loc, "Internal error: could not find Invoke method!");
+                               return false;
+                       }
+                       
+                       MethodBase mb = ((MethodGroupExpr) ml).Methods [0];
+                       ParameterData pd = Invocation.GetParameterData (mb);
+
+                       Expression probe_ml = Expression.MemberLookup (
+                               ec, delegate_type, "Invoke", loc);
+                       
+                       if (!(probe_ml is MethodGroupExpr)) {
+                               Report.Error (-100, loc, "Internal error: could not find Invoke method!");
+                               return false;
+                       }
+                       
+                       MethodBase probe_mb = ((MethodGroupExpr) probe_ml).Methods [0];
+                       ParameterData probe_pd = Invocation.GetParameterData (probe_mb);
+                       
+                       if (((MethodInfo) mb).ReturnType != ((MethodInfo) probe_mb).ReturnType)
+                               return false;
+
+                       if (pd.Count != probe_pd.Count)
+                               return false;
+
+                       for (int i = pd.Count; i > 0; ) {
+                               i--;
+
+                               if (pd.ParameterType (i) != probe_pd.ParameterType (i) ||
+                                   pd.ParameterModifier (i) != probe_pd.ParameterModifier (i))
+                                       return false;
+                       }
+                       
+                       return true;
+               }
+               
+               public static string FullDelegateDesc (Type del_type, MethodBase mb, ParameterData pd)
+               {
+                       StringBuilder sb = new StringBuilder (TypeManager.CSharpName (((MethodInfo) mb).ReturnType));
+                       
+                       sb.Append (" " + del_type.ToString ());
+                       sb.Append (" (");
+
+                       int length = pd.Count;
+                       
+                       for (int i = length; i > 0; ) {
+                               i--;
+
+                               sb.Append (pd.ParameterDesc (length - i - 1));
+                               if (i != 0)
+                                       sb.Append (", ");
+                       }
+                       
+                       sb.Append (")");
+                       return sb.ToString ();
+                       
+               }
+               
+               // Hack around System.Reflection as found everywhere else
+               public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
+                                                       MemberFilter filter, object criteria)
+               {
+                       ArrayList members = new ArrayList ();
+
+                       if ((mt & MemberTypes.Method) != 0) {
+                               if (ConstructorBuilder != null)
+                               if (filter (ConstructorBuilder, criteria))
+                                       members.Add (ConstructorBuilder);
+
+                               if (InvokeBuilder != null)
+                               if (filter (InvokeBuilder, criteria))
+                                       members.Add (InvokeBuilder);
+
+                               if (BeginInvokeBuilder != null)
+                               if (filter (BeginInvokeBuilder, criteria))
+                                       members.Add (BeginInvokeBuilder);
+
+                               if (EndInvokeBuilder != null)
+                               if (filter (EndInvokeBuilder, criteria))
+                                       members.Add (EndInvokeBuilder);
+                       }
+
+                       return new MemberList (members);
+               }
+
+               public override MemberCache MemberCache {
+                       get {
+                               return null;
+                       }
+               }
+
+               public Expression InstanceExpression {
+                       get {
+                               return instance_expr;
+                       }
+                       set {
+                               instance_expr = value;
+                       }
+               }
+
+               public MethodBase TargetMethod {
+                       get {
+                               return delegate_method;
+                       }
+                       set {
+                               delegate_method = value;
+                       }
+               }
+
+               public Type TargetReturnType {
+                       get {
+                               return ret_type;
+                       }
+               }
+
+               public Type [] ParameterTypes {
+                       get {
+                               return param_types;
+                       }
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Delegate;
+                       }
+               }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "T:"; }
+               }
+
+               protected override void VerifyObsoleteAttribute()
+               {
+                       CheckUsageOfObsoleteAttribute (ret_type);
+
+                       foreach (Type type in param_types) {
+                               CheckUsageOfObsoleteAttribute (type);
+                       }
+               }
+       }
+
+       //
+       // Base class for `NewDelegate' and `ImplicitDelegateCreation'
+       //
+       public abstract class DelegateCreation : Expression {
+               protected MethodBase constructor_method;
+               protected MethodBase delegate_method;
+               protected MethodGroupExpr method_group;
+               protected Expression delegate_instance_expression;
+
+               public DelegateCreation () {}
+
+               public static void Error_NoMatchingMethodForDelegate (EmitContext ec, MethodGroupExpr mg, Type type, Location loc)
+               {
+                       string method_desc;
+
+                       MethodBase candidate = mg.Methods [0];
+                       if (mg.Methods.Length > 1)
+                               method_desc = candidate.Name;
+                       else
+                               method_desc = Invocation.FullMethodDesc (candidate);
+
+                       Expression invoke_method = Expression.MemberLookup (
+                               ec, type, "Invoke", MemberTypes.Method,
+                               Expression.AllBindingFlags, loc);
+                       MethodBase method = ((MethodGroupExpr) invoke_method).Methods [0];
+                       ParameterData param = Invocation.GetParameterData (method);
+                       string delegate_desc = Delegate.FullDelegateDesc (type, method, param);
+
+                       if (!mg.HasTypeArguments &&
+                           !TypeManager.InferTypeArguments (ec, param, ref candidate))
+                               Report.Error (411, loc, "The type arguments for " +
+                                             "method `{0}' cannot be infered from " +
+                                             "the usage. Try specifying the type " +
+                                             "arguments explicitly.", method_desc);
+                       else
+                               Report.Error (123, loc, "Method '{0}' does not " +
+                                             "match delegate '{1}'", method_desc,
+                                             delegate_desc);
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       if (delegate_instance_expression == null || delegate_method.IsStatic)
+                               ec.ig.Emit (OpCodes.Ldnull);
+                       else
+                               delegate_instance_expression.Emit (ec);
+                       
+                       if (delegate_method.IsVirtual && !method_group.IsBase) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               ec.ig.Emit (OpCodes.Ldvirtftn, (MethodInfo) delegate_method);
+                       } else
+                               ec.ig.Emit (OpCodes.Ldftn, (MethodInfo) delegate_method);
+                       ec.ig.Emit (OpCodes.Newobj, (ConstructorInfo) constructor_method);
+               }
+
+               protected bool ResolveConstructorMethod (EmitContext ec)
+               {
+                       Expression ml = Expression.MemberLookup (
+                               ec, type, ".ctor", loc);
+
+                       if (!(ml is MethodGroupExpr)) {
+                               Report.Error (-100, loc, "Internal error: Could not find delegate constructor!");
+                               return false;
+                       }
+
+                       constructor_method = ((MethodGroupExpr) ml).Methods [0];
+                       return true;
+               }
+
+               protected Expression ResolveMethodGroupExpr (EmitContext ec, MethodGroupExpr mg)
+               {
+                               foreach (MethodInfo mi in mg.Methods){
+                                       delegate_method = Delegate.VerifyMethod (
+                                               ec, type, mi, loc);
+
+                                       if (delegate_method != null)
+                                               break;
+                               }
+                                       
+                               if (delegate_method == null) {
+                                       Error_NoMatchingMethodForDelegate (ec, mg, type, loc);
+                                       return null;
+                               }
+
+                               //
+                               // Check safe/unsafe of the delegate
+                               //
+                               if (!ec.InUnsafe){
+                                       ParameterData param = Invocation.GetParameterData (delegate_method);
+                                       int count = param.Count;
+                                       
+                                       for (int i = 0; i < count; i++){
+                                               if (param.ParameterType (i).IsPointer){
+                                                       Expression.UnsafeError (loc);
+                                                       return null;
+                                               }
+                                       }
+                               }
+                                               
+                       //TODO: implement caching when performance will be low
+                       IMethodData md = TypeManager.GetMethod (delegate_method);
+                       if (md == null) {
+                               if (System.Attribute.GetCustomAttribute (delegate_method, TypeManager.conditional_attribute_type) != null) {
+                                       Report.Error (1618, loc, "Cannot create delegate with '{0}' because it has a Conditional attribute", TypeManager.CSharpSignature (delegate_method));
+                               }
+                       } else {
+                               if (md.OptAttributes != null && md.OptAttributes.Search (TypeManager.conditional_attribute_type, ec) != null) {
+                                       Report.Error (1618, loc, "Cannot create delegate with '{0}' because it has a Conditional attribute", TypeManager.CSharpSignature (delegate_method));
+                               }
+                       }
+                       
+                       if (mg.InstanceExpression != null)
+                               delegate_instance_expression = mg.InstanceExpression.Resolve (ec);
+                       else if (ec.IsStatic) {
+                               if (!delegate_method.IsStatic) {
+                                       Report.Error (120, loc,
+                                                     "An object reference is required for the non-static method " +
+                                                     delegate_method.Name);
+                                       return null;
+                               }
+                               delegate_instance_expression = null;
+                       } else
+                               delegate_instance_expression = ec.GetThis (loc);
+
+                       if (delegate_instance_expression != null && delegate_instance_expression.Type.IsValueType)
+                               delegate_instance_expression = new BoxedCast (mg.InstanceExpression);
+
+                       method_group = mg;
+                       eclass = ExprClass.Value;
+                       return this;
+               }
+       }
+
+       //
+       // Created from the conversion code
+       //
+       public class ImplicitDelegateCreation : DelegateCreation {
+
+               ImplicitDelegateCreation (Type t, Location l)
+               {
+                       type = t;
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       return this;
+               }
+               
+               static public Expression Create (EmitContext ec, MethodGroupExpr mge, Type target_type, Location loc)
+               {
+                       ImplicitDelegateCreation d = new ImplicitDelegateCreation (target_type, loc);
+                       if (d.ResolveConstructorMethod (ec))
+                               return d.ResolveMethodGroupExpr (ec, mge);
+                       else
+                               return null;
+               }
+       }
+       
+       //
+       // A delegate-creation-expression, invoked from the `New' class 
+       //
+       public class NewDelegate : DelegateCreation {
+               public ArrayList Arguments;
+
+               //
+               // This constructor is invoked from the `New' expression
+               //
+               public NewDelegate (Type type, ArrayList Arguments, Location loc)
+               {
+                       this.type = type;
+                       this.Arguments = Arguments;
+                       this.loc  = loc; 
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if (Arguments == null || Arguments.Count != 1) {
+                               Report.Error (149, loc,
+                                             "Method name expected");
+                               return null;
+                       }
+
+                       if (!ResolveConstructorMethod (ec))
+                               return null;
+
+                       Argument a = (Argument) Arguments [0];
+                       
+                       if (!a.ResolveMethodGroup (ec, loc))
+                               return null;
+                       
+                       Expression e = a.Expr;
+
+                       if (e is AnonymousMethod && RootContext.Version != LanguageVersion.ISO_1)
+                               return ((AnonymousMethod) e).Compatible (ec, type, false);
+
+                       MethodGroupExpr mg = e as MethodGroupExpr;
+                       if (mg != null)
+                               return ResolveMethodGroupExpr (ec, mg);
+
+                       Type e_type = e.Type;
+
+                       if (!TypeManager.IsDelegateType (e_type)) {
+                               e.Error_UnexpectedKind ("method", loc);
+                               return null;
+                       }
+
+                       method_group = Expression.MemberLookup (
+                               ec, type, "Invoke", MemberTypes.Method,
+                               Expression.AllBindingFlags, loc) as MethodGroupExpr;
+
+                       if (method_group == null) {
+                               Report.Error (-200, loc, "Internal error ! Could not find Invoke method!");
+                               return null;
+                       }
+
+                       // This is what MS' compiler reports. We could always choose
+                       // to be more verbose and actually give delegate-level specifics
+                       if (!Delegate.VerifyDelegate (ec, type, e_type, loc)) {
+                               Report.Error (29, loc, "Cannot implicitly convert type '" + e_type + "' " +
+                                             "to type '" + type + "'");
+                               return null;
+                       }
+                               
+                       delegate_instance_expression = e;
+                       delegate_method = method_group.Methods [0];
+                       
+                       eclass = ExprClass.Value;
+                       return this;
+               }
+       }
+
+       public class DelegateInvocation : ExpressionStatement {
+
+               public Expression InstanceExpr;
+               public ArrayList  Arguments;
+
+               MethodBase method;
+               
+               public DelegateInvocation (Expression instance_expr, ArrayList args, Location loc)
+               {
+                       this.InstanceExpr = instance_expr;
+                       this.Arguments = args;
+                       this.loc = loc;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if (InstanceExpr is EventExpr) {
+                               
+                               EventInfo ei = ((EventExpr) InstanceExpr).EventInfo;
+                               
+                               Expression ml = MemberLookup (
+                                       ec, ec.ContainerType, ei.Name,
+                                       MemberTypes.Event, AllBindingFlags | BindingFlags.DeclaredOnly, loc);
+
+                               if (ml == null) {
+                                       //
+                                       // If this is the case, then the Event does not belong 
+                                       // to this Type and so, according to the spec
+                                       // cannot be accessed directly
+                                       //
+                                       // Note that target will not appear as an EventExpr
+                                       // in the case it is being referenced within the same type container;
+                                       // it will appear as a FieldExpr in that case.
+                                       //
+                                       
+                                       Assign.error70 (ei, loc);
+                                       return null;
+                               }
+                       }
+                       
+                       
+                       Type del_type = InstanceExpr.Type;
+                       if (del_type == null)
+                               return null;
+                       
+                       if (Arguments != null){
+                               foreach (Argument a in Arguments){
+                                       if (!a.Resolve (ec, loc))
+                                               return null;
+                               }
+                       }
+                       
+                       if (!Delegate.VerifyApplicability (ec, del_type, Arguments, loc))
+                               return null;
+
+                       Expression lookup = Expression.MemberLookup (ec, del_type, "Invoke", loc);
+                       if (!(lookup is MethodGroupExpr)) {
+                               Report.Error (-100, loc, "Internal error: could not find Invoke method!");
+                               return null;
+                       }
+                       
+                       method = ((MethodGroupExpr) lookup).Methods [0];
+                       type = ((MethodInfo) method).ReturnType;
+                       eclass = ExprClass.Value;
+                       
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       //
+                       // Invocation on delegates call the virtual Invoke member
+                       // so we are always `instance' calls
+                       //
+                       Invocation.EmitCall (ec, false, false, InstanceExpr, method, Arguments, loc);
+               }
+
+               public override void EmitStatement (EmitContext ec)
+               {
+                       Emit (ec);
+                       // 
+                       // Pop the return value if there is one
+                       //
+                       if (method is MethodInfo){
+                               if (((MethodInfo) method).ReturnType != TypeManager.void_type)
+                                       ec.ig.Emit (OpCodes.Pop);
+                       }
+               }
+
+       }
+}
diff --git a/mcs/bmcs/doc.cs b/mcs/bmcs/doc.cs
new file mode 100644 (file)
index 0000000..9c01411
--- /dev/null
@@ -0,0 +1,809 @@
+//
+// doc.cs: Support for XML documentation comment.
+//
+// Author:
+//     Atsushi Enomoto <atsushi@ximian.com>
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2004 Novell, Inc.
+//
+//
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.IO;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+using System.Security.Permissions;
+using System.Text;
+using System.Xml;
+
+using Mono.CompilerServices.SymbolWriter;
+
+namespace Mono.CSharp {
+
+       //
+       // Support class for XML documentation.
+       //
+       public static class DocUtil
+       {
+               // TypeContainer
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal static void GenerateTypeDocComment (TypeContainer t,
+                       DeclSpace ds)
+               {
+                       GenerateDocComment (t, ds);
+
+                       if (t.DefaultStaticConstructor != null)
+                               t.DefaultStaticConstructor.GenerateDocComment (t);
+
+                       if (t.InstanceConstructors != null)
+                               foreach (Constructor c in t.InstanceConstructors)
+                                       c.GenerateDocComment (t);
+
+                       if (t.Types != null)
+                               foreach (TypeContainer tc in t.Types)
+                                       tc.GenerateDocComment (t);
+
+                       if (t.Parts != null) {
+                               IDictionary comments = RootContext.Documentation.PartialComments;
+                               foreach (ClassPart cp in t.Parts) {
+                                       if (cp.DocComment == null)
+                                               continue;
+                                       comments [cp] = cp;
+                               }
+                       }
+
+                       if (t.Enums != null)
+                               foreach (Enum en in t.Enums)
+                                       en.GenerateDocComment (t);
+
+                       if (t.Constants != null)
+                               foreach (Const c in t.Constants)
+                                       c.GenerateDocComment (t);
+
+                       if (t.Fields != null)
+                               foreach (Field f in t.Fields)
+                                       f.GenerateDocComment (t);
+
+                       if (t.Events != null)
+                               foreach (Event e in t.Events)
+                                       e.GenerateDocComment (t);
+
+                       if (t.Indexers != null)
+                               foreach (Indexer ix in t.Indexers)
+                                       ix.GenerateDocComment (t);
+
+                       if (t.Properties != null)
+                               foreach (Property p in t.Properties)
+                                       p.GenerateDocComment (t);
+
+                       if (t.Methods != null)
+                               foreach (Method m in t.Methods)
+                                       m.GenerateDocComment (t);
+
+                       if (t.Operators != null)
+                               foreach (Operator o in t.Operators)
+                                       o.GenerateDocComment (t);
+               }
+
+               // MemberCore
+               private static readonly string lineHead =
+                       Environment.NewLine + "            ";
+
+               private static XmlNode GetDocCommentNode (MemberCore mc,
+                       string name)
+               {
+                       // FIXME: It could be even optimizable as not
+                       // to use XmlDocument. But anyways the nodes
+                       // are not kept in memory.
+                       XmlDocument doc = RootContext.Documentation.XmlDocumentation;
+                       try {
+                               XmlElement el = doc.CreateElement ("member");
+                               el.SetAttribute ("name", name);
+                               string normalized = mc.DocComment;
+                               el.InnerXml = normalized;
+                               // csc keeps lines as written in the sources
+                               // and inserts formatting indentation (which 
+                               // is different from XmlTextWriter.Formatting
+                               // one), but when a start tag contains an 
+                               // endline, it joins the next line. We don't
+                               // have to follow such a hacky behavior.
+                               string [] split =
+                                       normalized.Split ('\n');
+                               int j = 0;
+                               for (int i = 0; i < split.Length; i++) {
+                                       string s = split [i].TrimEnd ();
+                                       if (s.Length > 0)
+                                               split [j++] = s;
+                               }
+                               el.InnerXml = lineHead + String.Join (
+                                       lineHead, split, 0, j);
+                               return el;
+                       } catch (XmlException ex) {
+                               Report.Warning (1570, 1, mc.Location, "XML comment on '{0}' has non-well-formed XML ({1}).", name, ex.Message);
+                               XmlComment com = doc.CreateComment (String.Format ("FIXME: Invalid documentation markup was found for member {0}", name));
+                               return com;
+                       }
+               }
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal static void GenerateDocComment (MemberCore mc,
+                       DeclSpace ds)
+               {
+                       if (mc.DocComment != null) {
+                               string name = mc.GetDocCommentName (ds);
+
+                               XmlNode n = GetDocCommentNode (mc, name);
+
+                               XmlElement el = n as XmlElement;
+                               if (el != null) {
+                                       mc.OnGenerateDocComment (ds, el);
+
+                                       // FIXME: it could be done with XmlReader
+                                       foreach (XmlElement inc in n.SelectNodes (".//include"))
+                                               HandleInclude (mc, inc);
+
+                                       // FIXME: it could be done with XmlReader
+                                       DeclSpace dsTarget = mc as DeclSpace;
+                                       if (dsTarget == null)
+                                               dsTarget = ds;
+
+                                       foreach (XmlElement see in n.SelectNodes (".//see"))
+                                               HandleSee (mc, dsTarget, see);
+                                       foreach (XmlElement seealso in n.SelectNodes (".//seealso"))
+                                               HandleSeeAlso (mc, dsTarget, seealso);
+                                       foreach (XmlElement see in n.SelectNodes (".//exception"))
+                                               HandleException (mc, dsTarget, see);
+                               }
+
+                               n.WriteTo (RootContext.Documentation.XmlCommentOutput);
+                       }
+                       else if (mc.IsExposedFromAssembly (ds) &&
+                               // There are no warnings when the container also
+                               // misses documentations.
+                               (ds == null || ds.DocComment != null))
+                       {
+                               Report.Warning (1591, 4, mc.Location,
+                                       "Missing XML comment for publicly visible type or member '{0}'", mc.GetSignatureForError ());
+                       }
+               }
+
+               //
+               // Processes "include" element. Check included file and
+               // embed the document content inside this documentation node.
+               //
+               private static void HandleInclude (MemberCore mc, XmlElement el)
+               {
+                       string file = el.GetAttribute ("file");
+                       string path = el.GetAttribute ("path");
+                       if (file == "") {
+                               Report.Warning (1590, 1, mc.Location, "Invalid XML 'include' element; Missing 'file' attribute.");
+                               el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el);
+                       }
+                       else if (path == "") {
+                               Report.Warning (1590, 1, mc.Location, "Invalid XML 'include' element; Missing 'path' attribute.");
+                               el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Include tag is invalid "), el);
+                       }
+                       else {
+                               XmlDocument doc = RootContext.Documentation.StoredDocuments [file] as XmlDocument;
+                               if (doc == null) {
+                                       try {
+                                               doc = new XmlDocument ();
+                                               doc.Load (file);
+                                               RootContext.Documentation.StoredDocuments.Add (file, doc);
+                                       } catch (Exception) {
+                                               el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (String.Format (" Badly formed XML in at comment file '{0}': cannot be included ", file)), el);
+                                               Report.Warning (1592, 1, mc.Location, "Badly formed XML in included comments file -- '{0}'", file);
+                                       }
+                               }
+                               bool keepIncludeNode = false;
+                               if (doc != null) {
+                                       try {
+                                               XmlNodeList nl = doc.SelectNodes (path);
+                                               if (nl.Count == 0) {
+                                                       el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" No matching elements were found for the include tag embedded here. "), el);
+                                       
+                                                       keepIncludeNode = true;
+                                               }
+                                               foreach (XmlNode n in nl)
+                                                       el.ParentNode.InsertBefore (el.OwnerDocument.ImportNode (n, true), el);
+                                       } catch (Exception ex) {
+                                               el.ParentNode.InsertBefore (el.OwnerDocument.CreateComment (" Failed to insert some or all of included XML "), el);
+                                               Report.Warning (1589, 1, mc.Location, "Unable to include XML fragment '{0}' of file {1} -- {2}.", path, file, ex.Message);
+                                       }
+                               }
+                               if (!keepIncludeNode)
+                                       el.ParentNode.RemoveChild (el);
+                       }
+               }
+
+               //
+               // Handles <see> elements.
+               //
+               private static void HandleSee (MemberCore mc,
+                       DeclSpace ds, XmlElement see)
+               {
+                       HandleXrefCommon (mc, ds, see);
+               }
+
+               //
+               // Handles <seealso> elements.
+               //
+               private static void HandleSeeAlso (MemberCore mc,
+                       DeclSpace ds, XmlElement seealso)
+               {
+                       HandleXrefCommon (mc, ds, seealso);
+               }
+
+               //
+               // Handles <exception> elements.
+               //
+               private static void HandleException (MemberCore mc,
+                       DeclSpace ds, XmlElement seealso)
+               {
+                       HandleXrefCommon (mc, ds, seealso);
+               }
+
+               static readonly char [] wsChars =
+                       new char [] {' ', '\t', '\n', '\r'};
+
+               //
+               // returns a full runtime type name from a name which might
+               // be C# specific type name.
+               //
+               private static Type FindDocumentedType (MemberCore mc,
+                       string name, DeclSpace ds, bool allowAlias)
+               {
+                       bool isArray = false;
+                       string identifier = name;
+                       if (name [name.Length - 1] == ']') {
+                               string tmp = name.Substring (0, name.Length - 1).Trim (wsChars);
+                               if (tmp [tmp.Length - 1] == '[') {
+                                       identifier = tmp.Substring (0, tmp.Length - 1).Trim (wsChars);
+                                       isArray = true;
+                               }
+                       }
+                       Type t = FindDocumentedTypeNonArray (mc, identifier,
+                               ds, allowAlias);
+                       if (t != null && isArray)
+                               t = Array.CreateInstance (t, 0).GetType ();
+                       return t;
+               }
+
+               private static Type FindDocumentedTypeNonArray (MemberCore mc,
+                       string identifier, DeclSpace ds, bool allowAlias)
+               {
+                       switch (identifier) {
+                       case "int":
+                               return typeof (int);
+                       case "uint":
+                               return typeof (uint);
+                       case "short":
+                               return typeof (short);
+                       case "ushort":
+                               return typeof (ushort);
+                       case "long":
+                               return typeof (long);
+                       case "ulong":
+                               return typeof (ulong);
+                       case "float":
+                               return typeof (float);
+                       case "double":
+                               return typeof (double);
+                       case "char":
+                               return typeof (char);
+                       case "decimal":
+                               return typeof (decimal);
+                       case "byte":
+                               return typeof (byte);
+                       case "sbyte":
+                               return typeof (sbyte);
+                       case "object":
+                               return typeof (object);
+                       case "bool":
+                               return typeof (bool);
+                       case "string":
+                               return typeof (string);
+                       case "void":
+                               return typeof (void);
+                       }
+                       if (allowAlias) {
+                               IAlias alias = ds.LookupAlias (identifier);
+                               if (alias != null)
+                                       identifier = alias.Name;
+                       }
+                       Type t = ds.FindType (mc.Location, identifier);
+                       if (t == null)
+                               t = TypeManager.LookupTypeDirect (identifier);
+                       return t;
+               }
+
+               //
+               // Returns a MemberInfo that is referenced in XML documentation
+               // (by "see" or "seealso" elements).
+               //
+               private static MemberInfo FindDocumentedMember (MemberCore mc,
+                       Type type, string memberName, Type [] paramList, 
+                       DeclSpace ds, out int warningType, string cref)
+               {
+                       warningType = 0;
+                       MethodSignature msig = new MethodSignature (memberName, null, paramList);
+                       MemberInfo [] mis = type.FindMembers (
+                               MemberTypes.All,
+                               BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
+                               MethodSignature.method_signature_filter,
+                               msig);
+                       if (mis.Length > 0)
+                               return mis [0];
+
+                       if (paramList.Length == 0) {
+                               // search for fields/events etc.
+                               mis = type.FindMembers (
+                                       MemberTypes.All,
+                                       BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance,
+                                       Type.FilterName,
+                                       memberName);
+                               return (mis.Length > 0) ? mis [0] : null;
+                       }
+
+                       // search for operators (whose parameters exactly
+                       // matches with the list) and possibly report CS1581.
+                       string oper = null;
+                       string returnTypeName = null;
+                       if (memberName.StartsWith ("implicit operator ")) {
+                               oper = "op_Implicit";
+                               returnTypeName = memberName.Substring (18).Trim (wsChars);
+                       }
+                       else if (memberName.StartsWith ("explicit operator ")) {
+                               oper = "op_Explicit";
+                               returnTypeName = memberName.Substring (18).Trim (wsChars);
+                       }
+                       else if (memberName.StartsWith ("operator ")) {
+                               oper = memberName.Substring (9).Trim (wsChars);
+                               switch (oper) {
+                               // either unary or binary
+                               case "+":
+                                       oper = paramList.Length == 2 ?
+                                               Binary.oper_names [(int) Binary.Operator.Addition] :
+                                               Unary.oper_names [(int) Unary.Operator.UnaryPlus];
+                                       break;
+                               case "-":
+                                       oper = paramList.Length == 2 ?
+                                               Binary.oper_names [(int) Binary.Operator.Subtraction] :
+                                               Unary.oper_names [(int) Unary.Operator.UnaryNegation];
+                                       break;
+                               // unary
+                               case "!":
+                                       oper = Unary.oper_names [(int) Unary.Operator.LogicalNot]; break;
+                               case "~":
+                                       oper = Unary.oper_names [(int) Unary.Operator.OnesComplement]; break;
+                                       
+                               case "++":
+                                       oper = "op_Increment"; break;
+                               case "--":
+                                       oper = "op_Decrement"; break;
+                               case "true":
+                                       oper = "op_True"; break;
+                               case "false":
+                                       oper = "op_False"; break;
+                               // binary
+                               case "*":
+                                       oper = Binary.oper_names [(int) Binary.Operator.Multiply]; break;
+                               case "/":
+                                       oper = Binary.oper_names [(int) Binary.Operator.Division]; break;
+                               case "%":
+                                       oper = Binary.oper_names [(int) Binary.Operator.Modulus]; break;
+                               case "&":
+                                       oper = Binary.oper_names [(int) Binary.Operator.BitwiseAnd]; break;
+                               case "|":
+                                       oper = Binary.oper_names [(int) Binary.Operator.BitwiseOr]; break;
+                               case "^":
+                                       oper = Binary.oper_names [(int) Binary.Operator.ExclusiveOr]; break;
+                               case "<<":
+                                       oper = Binary.oper_names [(int) Binary.Operator.LeftShift]; break;
+                               case ">>":
+                                       oper = Binary.oper_names [(int) Binary.Operator.RightShift]; break;
+                               case "==":
+                                       oper = Binary.oper_names [(int) Binary.Operator.Equality]; break;
+                               case "!=":
+                                       oper = Binary.oper_names [(int) Binary.Operator.Inequality]; break;
+                               case "<":
+                                       oper = Binary.oper_names [(int) Binary.Operator.LessThan]; break;
+                               case ">":
+                                       oper = Binary.oper_names [(int) Binary.Operator.GreaterThan]; break;
+                               case "<=":
+                                       oper = Binary.oper_names [(int) Binary.Operator.LessThanOrEqual]; break;
+                               case ">=":
+                                       oper = Binary.oper_names [(int) Binary.Operator.GreaterThanOrEqual]; break;
+                               default:
+                                       warningType = 1584;
+                                       Report.Warning (1020, 1, mc.Location, "Overloadable {0} operator is expected", paramList.Length == 2 ? "binary" : "unary");
+                                       Report.Warning (1584, 1, mc.Location, "XML comment on '{0}' has syntactically incorrect attribute '{1}'", mc.GetSignatureForError (), cref);
+                                       return null;
+                               }
+                       }
+                       // here we still does not consider return type (to
+                       // detect CS1581 or CS1002+CS1584).
+                       msig = new MethodSignature (oper, null, paramList);
+                       mis = type.FindMembers (
+                               MemberTypes.Method,
+                               BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static,
+                               MethodSignature.method_signature_filter,
+                               msig);
+                       if (mis.Length == 0)
+                               return null; // CS1574
+                       MemberInfo mi = mis [0];
+                       Type expected = mi is MethodInfo ?
+                               ((MethodInfo) mi).ReturnType :
+                               mi is PropertyInfo ?
+                               ((PropertyInfo) mi).PropertyType :
+                               null;
+                       if (returnTypeName != null) {
+                               Type returnType = FindDocumentedType (mc, returnTypeName, ds, true);
+                               if (returnType == null || returnType != expected) {
+                                       warningType = 1581;
+                                       Report.Warning (1581, 1, mc.Location, "Invalid return type in XML comment cref attribute '{0}'", cref);
+                                       return null;
+                               }
+                       }
+                       return mis [0];
+               }
+
+               private static Type [] emptyParamList = new Type [0];
+
+               //
+               // Processes "see" or "seealso" elements.
+               // Checks cref attribute.
+               //
+               private static void HandleXrefCommon (MemberCore mc,
+                       DeclSpace ds, XmlElement xref)
+               {
+                       string cref = xref.GetAttribute ("cref").Trim (wsChars);
+                       // when, XmlReader, "if (cref == null)"
+                       if (!xref.HasAttribute ("cref"))
+                               return;
+                       if (cref.Length == 0)
+                               Report.Warning (1001, 1, mc.Location, "Identifier expected");
+                               // ... and continue until CS1584.
+
+                       string signature; // "x:" are stripped
+                       string name; // method invokation "(...)" are removed
+                       string identifiers; // array indexer "[]" are removed
+                       string parameters; // method parameter list
+
+                       // strip 'T:' 'M:' 'F:' 'P:' 'E:' etc.
+                       // Here, MS ignores its member kind. No idea why.
+                       if (cref.Length > 2 && cref [1] == ':')
+                               signature = cref.Substring (2).Trim (wsChars);
+                       else
+                               signature = cref;
+
+                       int parensPos = signature.IndexOf ('(');
+                       if (parensPos > 0 && signature [signature.Length - 1] == ')') {
+                               name = signature.Substring (0, parensPos).Trim (wsChars);
+                               parameters = signature.Substring (parensPos + 1, signature.Length - parensPos - 2);
+                       }
+                       else {
+                               name = signature;
+                               parameters = String.Empty;
+                       }
+
+                       string identifier = name;
+
+                       if (name.Length > 0 && name [name.Length - 1] == ']') {
+                               string tmp = name.Substring (0, name.Length - 1).Trim (wsChars);
+                               if (tmp [tmp.Length - 1] == '[')
+                                       identifier = tmp.Substring (0, tmp.Length - 1).Trim (wsChars);
+                       }
+
+                       // Check if identifier is valid.
+                       // This check is not necessary to mark as error, but
+                       // csc specially reports CS1584 for wrong identifiers.
+                       foreach (string nameElem in identifier.Split ('.')) {
+                               if (!Tokenizer.IsValidIdentifier (nameElem)
+                                       && nameElem.IndexOf ("operator") < 0) {
+                                       if (nameElem.EndsWith ("[]") &&
+                                               Tokenizer.IsValidIdentifier (
+                                               nameElem.Substring (
+                                               0, nameElem.Length - 2)))
+                                               continue;
+
+                                       Report.Warning (1584, 1, mc.Location, "XML comment on '{0}' has syntactically incorrect attribute '{1}'", mc.GetSignatureForError (), cref);
+                                       xref.SetAttribute ("cref", "!:" + signature);
+                                       return;
+                               }
+                       }
+
+                       // check if parameters are valid
+                       Type [] parameterTypes = emptyParamList;
+                       if (parameters.Length > 0) {
+                               string [] paramList = parameters.Split (',');
+                               ArrayList plist = new ArrayList ();
+                               for (int i = 0; i < paramList.Length; i++) {
+                                       string paramTypeName = paramList [i].Trim (wsChars);
+                                       Type paramType = FindDocumentedType (mc, paramTypeName, ds, true);
+                                       if (paramType == null) {
+                                               Report.Warning (1580, 1, mc.Location, "Invalid type for parameter '{0}' in XML comment cref attribute '{1}'", i + 1, cref);
+                                               return;
+                                       }
+                                       plist.Add (paramType);
+                               }
+                               parameterTypes = plist.ToArray (typeof (Type)) as Type [];
+                               StringBuilder sb = new StringBuilder ();
+                               sb.Append ('(');
+                               for (int i = 0; i < parameterTypes.Length; i++) {
+                                       Type t = parameterTypes [i];
+                                       if (sb.Length > 1)
+                                               sb.Append (',');
+                                       sb.Append (t.FullName.Replace ('+', '.'));
+                               }
+                               sb.Append (')');
+                               parameters = sb.ToString ();
+                       }
+
+                       Type type = FindDocumentedType (mc, name, ds, true);
+                       if (type != null) {
+                               xref.SetAttribute ("cref", "T:" + type.FullName.Replace ("+", "."));
+                               return; // a type
+                       }
+
+                       // don't use identifier here. System[] is not alloed.
+                       if (Namespace.IsNamespace (name)) {
+                               xref.SetAttribute ("cref", "N:" + name);
+                               return; // a namespace
+                       }
+
+                       int period = name.LastIndexOf ('.');
+                       if (period > 0) {
+                               string typeName = name.Substring (0, period);
+                               string memberName = name.Substring (period + 1);
+                               type = FindDocumentedType (mc, typeName, ds, false);
+                               int warnResult;
+                               if (type != null) {
+                                       MemberInfo mi = FindDocumentedMember (mc, type, memberName, parameterTypes, ds, out warnResult, cref);
+                                       if (warnResult > 0)
+                                               return;
+                                       if (mi != null) {
+                                               xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + type.FullName.Replace ("+", ".") + "." + memberName + parameters);
+                                               return; // a member of a type
+                                       }
+                               }
+                       }
+                       else {
+                               int warnResult;
+                               MemberInfo mi = FindDocumentedMember (mc, ds.TypeBuilder, name, parameterTypes, ds, out warnResult, cref);
+                               if (warnResult > 0)
+                                       return;
+                               if (mi != null) {
+                                       xref.SetAttribute ("cref", GetMemberDocHead (mi.MemberType) + ds.TypeBuilder.FullName.Replace ("+", ".") + "." + name);
+                                       return; // local member name
+                               }
+                       }
+
+                       Report.Warning (1574, 1, mc.Location, "XML comment on '{0}' has cref attribute '{1}' that could not be resolved in '{2}'.", mc.GetSignatureForError (), cref, ds.GetSignatureForError ());
+
+                       xref.SetAttribute ("cref", "!:" + name);
+               }
+
+               //
+               // Get a prefix from member type for XML documentation (used
+               // to formalize cref target name).
+               //
+               static string GetMemberDocHead (MemberTypes type)
+               {
+                       switch (type) {
+                       case MemberTypes.Constructor:
+                       case MemberTypes.Method:
+                               return "M:";
+                       case MemberTypes.Event:
+                               return "E:";
+                       case MemberTypes.Field:
+                               return "F:";
+                       case MemberTypes.NestedType:
+                       case MemberTypes.TypeInfo:
+                               return "T:";
+                       case MemberTypes.Property:
+                               return "P:";
+                       }
+                       return "!:";
+               }
+
+               // MethodCore
+
+               //
+               // Returns a string that represents the signature for this 
+               // member which should be used in XML documentation.
+               //
+               public static string GetMethodDocCommentName (MethodCore mc, DeclSpace ds)
+               {
+                       Parameter [] plist = mc.Parameters.FixedParameters;
+                       Parameter parr = mc.Parameters.ArrayParameter;
+                       string paramSpec = String.Empty;
+                       if (plist != null) {
+                               StringBuilder psb = new StringBuilder ();
+                               foreach (Parameter p in plist) {
+                                       psb.Append (psb.Length != 0 ? "," : "(");
+                                       psb.Append (p.ParameterType.FullName.Replace ("+", "."));
+                               }
+                               paramSpec = psb.ToString ();
+                       }
+                       if (parr != null)
+                               paramSpec += String.Concat (
+                                       paramSpec == String.Empty ? "(" : ",",
+                                       parr.ParameterType.FullName.Replace ("+", "."));
+
+                       if (paramSpec.Length > 0)
+                               paramSpec += ")";
+
+                       string name = mc is Constructor ? "#ctor" : mc.Name;
+                       return String.Concat (mc.DocCommentHeader, ds.Name, ".", name, paramSpec);
+               }
+
+               //
+               // Raised (and passed an XmlElement that contains the comment)
+               // when GenerateDocComment is writing documentation expectedly.
+               //
+               // FIXME: with a few effort, it could be done with XmlReader,
+               // that means removal of DOM use.
+               //
+               internal static void OnMethodGenerateDocComment (
+                       MethodCore mc, DeclSpace ds, XmlElement el)
+               {
+                       Hashtable paramTags = new Hashtable ();
+                       foreach (XmlElement pelem in el.SelectNodes ("param")) {
+                               int i;
+                               string xname = pelem.GetAttribute ("name");
+                               if (xname == "")
+                                       continue; // really? but MS looks doing so
+                               if (xname != "" && mc.Parameters.GetParameterByName (xname, out i) == null)
+                                       Report.Warning (1572, 2, mc.Location, "XML comment on '{0}' has a 'param' tag for '{1}', but there is no such parameter.", mc.Name, xname);
+                               else if (paramTags [xname] != null)
+                                       Report.Warning (1571, 2, mc.Location, "XML comment on '{0}' has a duplicate param tag for '{1}'", mc.Name, xname);
+                               paramTags [xname] = xname;
+                       }
+                       Parameter [] plist = mc.Parameters.FixedParameters;
+                       Parameter parr = mc.Parameters.ArrayParameter;
+                       if (plist != null) {
+                               foreach (Parameter p in plist) {
+                                       if (paramTags.Count > 0 && paramTags [p.Name] == null)
+                                               Report.Warning (1573, 4, mc.Location, "Parameter '{0}' has no matching param tag in the XML comment for '{1}' (but other parameters do)", mc.Name, p.Name);
+                               }
+                       }
+               }
+
+               // Enum
+               public static void GenerateEnumDocComment (Enum e, DeclSpace ds)
+               {
+                       GenerateDocComment (e, ds);
+                       foreach (string name in e.ordered_enums) {
+                               MemberCore mc = e.GetDefinition (name);
+                               GenerateDocComment (mc, e);
+                       }
+               }
+       }
+
+       //
+       // Implements XML documentation generation.
+       //
+       public class Documentation
+       {
+               public Documentation (string xml_output_filename)
+               {
+                       docfilename = xml_output_filename;
+                       XmlDocumentation = new XmlDocument ();
+                       XmlDocumentation.PreserveWhitespace = false;
+               }
+
+               private string docfilename;
+
+               //
+               // Used to create element which helps well-formedness checking.
+               //
+               public XmlDocument XmlDocumentation;
+
+               //
+               // The output for XML documentation.
+               //
+               public XmlWriter XmlCommentOutput;
+
+               //
+               // Stores XmlDocuments that are included in XML documentation.
+               // Keys are included filenames, values are XmlDocuments.
+               //
+               public Hashtable StoredDocuments = new Hashtable ();
+
+               //
+               // Stores comments on partial types (should handle uniquely).
+               // Keys are PartialContainers, values are comment strings
+               // (didn't use StringBuilder; usually we have just 2 or more).
+               //
+               public IDictionary PartialComments = new ListDictionary ();
+
+               //
+               // Outputs XML documentation comment from tokenized comments.
+               //
+               public bool OutputDocComment (string asmfilename)
+               {
+                       XmlTextWriter w = null;
+                       try {
+                               w = new XmlTextWriter (docfilename, null);
+                               w.Indentation = 4;
+                               w.Formatting = Formatting.Indented;
+                               w.WriteStartDocument ();
+                               w.WriteStartElement ("doc");
+                               w.WriteStartElement ("assembly");
+                               w.WriteStartElement ("name");
+                               w.WriteString (Path.ChangeExtension (asmfilename, null));
+                               w.WriteEndElement (); // name
+                               w.WriteEndElement (); // assembly
+                               w.WriteStartElement ("members");
+                               XmlCommentOutput = w;
+                               GenerateDocComment ();
+                               w.WriteFullEndElement (); // members
+                               w.WriteEndElement ();
+                               w.WriteWhitespace (Environment.NewLine);
+                               w.WriteEndDocument ();
+                               return true;
+                       } catch (Exception ex) {
+                               Report.Error (1569, "Error generating XML documentation file '{0}' ('{1}')", docfilename, ex.Message);
+                               return false;
+                       } finally {
+                               if (w != null)
+                                       w.Close ();
+                       }
+               }
+
+               //
+               // Fixes full type name of each documented types/members up.
+               //
+               public void GenerateDocComment ()
+               {
+                       TypeContainer root = RootContext.Tree.Types;
+                       if (root.Interfaces != null)
+                               foreach (Interface i in root.Interfaces) 
+                                       DocUtil.GenerateTypeDocComment (i, null);
+
+                       if (root.Types != null)
+                               foreach (TypeContainer tc in root.Types)
+                                       DocUtil.GenerateTypeDocComment (tc, null);
+
+                       if (root.Parts != null) {
+                               IDictionary comments = PartialComments;
+                               foreach (ClassPart cp in root.Parts) {
+                                       if (cp.DocComment == null)
+                                               continue;
+                                       comments [cp] = cp;
+                               }
+                       }
+
+                       if (root.Delegates != null)
+                               foreach (Delegate d in root.Delegates) 
+                                       DocUtil.GenerateDocComment (d, null);
+
+                       if (root.Enums != null)
+                               foreach (Enum e in root.Enums)
+                                       DocUtil.GenerateEnumDocComment (e, null);
+
+                       IDictionary table = new ListDictionary ();
+                       foreach (ClassPart cp in PartialComments.Keys) {
+                               table [cp.PartialContainer] += cp.DocComment;
+                       }
+                       foreach (PartialContainer pc in table.Keys) {
+                               pc.DocComment = table [pc] as string;
+                               DocUtil.GenerateDocComment (pc, null);
+                       }
+               }
+       }
+}
diff --git a/mcs/bmcs/driver.cs b/mcs/bmcs/driver.cs
new file mode 100644 (file)
index 0000000..c769725
--- /dev/null
@@ -0,0 +1,1768 @@
+//
+// driver.cs: The compiler command line driver.
+//
+// Author: Miguel de Icaza (miguel@gnu.org)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
+//
+
+namespace Mono.CSharp
+{
+       using System;
+       using System.Reflection;
+       using System.Reflection.Emit;
+       using System.Collections;
+       using System.Diagnostics;
+       using System.IO;
+       using System.Text;
+       using System.Globalization;
+       using System.Xml;
+       using System.Diagnostics;
+
+       public enum Target {
+               Library, Exe, Module, WinExe
+       };
+       
+       /// <summary>
+       ///    The compiler driver.
+       /// </summary>
+       public class Driver
+       {
+               
+               //
+               // Assemblies references to be linked.   Initialized with
+               // mscorlib.dll here.
+               static ArrayList references;
+
+               //
+               // If any of these fail, we ignore the problem.  This is so
+               // that we can list all the assemblies in Windows and not fail
+               // if they are missing on Linux.
+               //
+               static ArrayList soft_references;
+
+               //
+               // Modules to be linked
+               //
+               static ArrayList modules;
+
+               // Lookup paths
+               static ArrayList link_paths;
+
+               // Whether we want to only run the tokenizer
+               static bool tokenize = false;
+               
+               static string first_source;
+
+               static bool want_debugging_support = false;
+
+               static bool parse_only = false;
+               static bool timestamps = false;
+               static bool pause = false;
+               static bool show_counters = false;
+               public static bool parser_verbose = false;
+               
+               //
+               // Whether to load the initial config file (what CSC.RSP has by default)
+               // 
+               static bool load_default_config = true;
+
+               static Hashtable response_file_list;
+
+               //
+               // A list of resource files
+               //
+               static ArrayList resources;
+               static ArrayList embedded_resources;
+               static string win32ResourceFile;
+               static string win32IconFile;
+               
+               //
+               // An array of the defines from the command line
+               //
+               static ArrayList defines;
+
+               //
+               // Output file
+               //
+               static string output_file = null;
+
+               //
+               // Last time we took the time
+               //
+               static DateTime last_time, first_time;
+
+               //
+               // Encoding: ISO-Latin1 is 28591
+               //
+               static Encoding encoding;
+
+               //
+               // Whether the user has specified a different encoder manually
+               //
+               static bool using_default_encoder = true;
+
+               public static void ShowTime (string msg)
+               {
+                       if (!timestamps)
+                               return;
+
+                       DateTime now = DateTime.Now;
+                       TimeSpan span = now - last_time;
+                       last_time = now;
+
+                       Console.WriteLine (
+                               "[{0:00}:{1:000}] {2}",
+                               (int) span.TotalSeconds, span.Milliseconds, msg);
+               }
+
+               public static void ShowTotalTime (string msg)
+               {
+                       if (!timestamps)
+                               return;
+
+                       DateTime now = DateTime.Now;
+                       TimeSpan span = now - first_time;
+                       last_time = now;
+
+                       Console.WriteLine (
+                               "[{0:00}:{1:000}] {2}",
+                               (int) span.TotalSeconds, span.Milliseconds, msg);
+               }              
+              
+               static void tokenize_file (SourceFile file)
+               {
+                       Stream input;
+
+                       try {
+                               input = File.OpenRead (file.Name);
+                       } catch {
+                               Report.Error (2001, "Source file '" + file.Name + "' could not be opened");
+                               return;
+                       }
+
+                       using (input){
+                               SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
+                               Tokenizer lexer = new Tokenizer (reader, file, defines);
+                               int token, tokens = 0, errors = 0;
+
+                               while ((token = lexer.token ()) != Token.EOF){
+                                       tokens++;
+                                       if (token == Token.ERROR)
+                                               errors++;
+                               }
+                               Console.WriteLine ("Tokenized: " + tokens + " found " + errors + " errors");
+                       }
+                       
+                       return;
+               }
+
+               // MonoTODO("Change error code for aborted compilation to something reasonable")]               
+               static void parse (SourceFile file)
+               {
+                       CSharpParser parser;
+                       Stream input;
+
+                       try {
+                               input = File.OpenRead (file.Name);
+                       } catch {
+                               Report.Error (2001, "Source file '" + file.Name + "' could not be opened");
+                               return;
+                       }
+
+                       SeekableStreamReader reader = new SeekableStreamReader (input, encoding, using_default_encoder);
+                               
+                       parser = new CSharpParser (reader, file, defines);
+                       try {
+                               parser.parse ();
+                       } catch (Exception ex) {
+                               Report.Error(666, "Compilation aborted: " + ex);
+                       } finally {
+                               input.Close ();
+                       }
+               }
+               
+               static void OtherFlags ()
+               {
+                       Console.WriteLine (
+                               "Other flags in the compiler\n" +
+                               "   --fatal            Makes errors fatal\n" +
+                               "   --parse            Only parses the source file\n" +
+                               "   --stacktrace       Shows stack trace at error location\n" +
+                               "   --timestamp        Displays time stamps of various compiler events\n" +
+                               "   -2                 Enables experimental C# features\n" +
+                               "   -v                 Verbose parsing (for debugging the parser)\n" + 
+                               "   --mcs-debug X      Sets MCS debugging level to X\n");
+               }
+               
+               static void Usage ()
+               {
+                       Console.WriteLine (
+                               "Mono C# compiler, (C) 2001 - 2003 Ximian, Inc.\n" +
+                               "mcs [options] source-files\n" +
+                               "   --about            About the Mono C# compiler\n" +
+                               "   -addmodule:MODULE  Adds the module to the generated assembly\n" + 
+                               "   -checked[+|-]      Set default context to checked\n" +
+                               "   -codepage:ID       Sets code page to the one in ID\n" +
+                               "                      (number, `utf8' or `reset')\n" +
+                               "   -clscheck[+|-]     Disables CLS Compliance verifications" + Environment.NewLine +
+                               "   -define:S1[;S2]    Defines one or more symbols (short: /d:)\n" +
+                               "   -debug[+|-]        Generate debugging information\n" + 
+                               "   -delaysign[+|-]    Only insert the public key into the assembly (no signing)\n" +
+                               "   -doc:FILE          XML Documentation file to generate\n" + 
+                               "   -g                 Generate debugging information\n" +
+                               "   -keycontainer:NAME The key pair container used to strongname the assembly\n" +
+                               "   -keyfile:FILE      The strongname key file used to strongname the assembly\n" +
+                               "   -langversion:TEXT  Specifies language version modes: ISO-1 or Default" + Environment.NewLine +
+                               "   -lib:PATH1,PATH2   Adds the paths to the assembly link path\n" +
+                               "   -main:class        Specified the class that contains the entry point\n" +
+                               "   -noconfig[+|-]     Disables implicit references to assemblies\n" +
+                               "   -nostdlib[+|-]     Does not load core libraries\n" +
+                               "   -nowarn:W1[,W2]    Disables one or more warnings\n" + 
+                               "   -out:FNAME         Specifies output file\n" +
+                               "   -doc:XMLFILE         Generates xml documentation into specified file\n" +
+                               "   -pkg:P1[,Pn]       References packages P1..Pn\n" + 
+                               "   --expect-error X   Expect that error X will be encountered\n" +
+                               "   -recurse:SPEC      Recursively compiles the files in SPEC ([dir]/file)\n" + 
+                               "   -reference:ASS     References the specified assembly (-r:ASS)\n" +
+                               "   -target:KIND       Specifies the target (KIND is one of: exe, winexe,\n" +
+                               "                      library, module), (short: /t:)\n" +
+                               "   -unsafe[+|-]       Allows unsafe code\n" +
+                               "   -warnaserror[+|-]  Treat warnings as errors\n" +
+                               "   -warn:LEVEL        Sets warning level (the highest is 4, the default is 2)\n" +
+                               "   -help2             Show other help flags\n" + 
+                               "\n" +
+                               "Resources:\n" +
+                               "   -linkresource:FILE[,ID] Links FILE as a resource\n" +
+                               "   -resource:FILE[,ID]     Embed FILE as a resource\n" +
+                               "   -win32res:FILE          Specifies Win32 resource file (.res)\n" +
+                               "   -win32icon:FILE         Use this icon for the output\n" +
+                                "   @file              Read response file for more options\n\n" +
+                               "Options can be of the form -option or /option");
+               }
+
+               static void TargetUsage ()
+               {
+                       Report.Error (2019, "Valid options for -target: are exe, winexe, library or module");
+               }
+               
+               static void About ()
+               {
+                       Console.WriteLine (
+                               "The Mono C# compiler is (C) 2001, 2002, 2003 Ximian, Inc.\n\n" +
+                               "The compiler source code is released under the terms of the GNU GPL\n\n" +
+
+                               "For more information on Mono, visit the project Web site\n" +
+                               "   http://www.go-mono.com\n\n" +
+
+                               "The compiler was written by Miguel de Icaza, Ravi Pratap, Martin Baulig and Marek Safar");
+                       Environment.Exit (0);
+               }
+
+               public static int counter1, counter2;
+               
+               public static int Main (string[] args)
+               {
+                       RootContext.Version = LanguageVersion.Default;
+                       bool ok = MainDriver (args);
+                       
+                       if (ok && Report.Errors == 0) {
+                               Console.Write("Compilation succeeded");
+                               if (Report.Warnings > 0) {
+                                       Console.Write(" - {0} warning(s)", Report.Warnings);
+                               }
+                               Console.WriteLine();
+                               if (show_counters){
+                                       Console.WriteLine ("Counter1: " + counter1);
+                                       Console.WriteLine ("Counter2: " + counter2);
+                               }
+                               if (pause)
+                                       Console.ReadLine ();
+                               return 0;
+                       } else {
+                               Console.WriteLine("Compilation failed: {0} error(s), {1} warnings",
+                                       Report.Errors, Report.Warnings);
+                               return 1;
+                       }
+               }
+
+               static public void LoadAssembly (string assembly, bool soft)
+               {
+                       Assembly a;
+                       string total_log = "";
+
+                       try {
+                               char[] path_chars = { '/', '\\' };
+
+                               if (assembly.IndexOfAny (path_chars) != -1) {
+                                       a = Assembly.LoadFrom (assembly);
+                               } else {
+                                       string ass = assembly;
+                                       if (ass.EndsWith (".dll"))
+                                               ass = assembly.Substring (0, assembly.Length - 4);
+                                       a = Assembly.Load (ass);
+                               }
+                               TypeManager.AddAssembly (a);
+
+                       } catch (FileNotFoundException){
+                               foreach (string dir in link_paths){
+                                       string full_path = Path.Combine (dir, assembly);
+                                       if (!assembly.EndsWith (".dll"))
+                                               full_path += ".dll";
+
+                                       try {
+                                               a = Assembly.LoadFrom (full_path);
+                                               TypeManager.AddAssembly (a);
+                                               return;
+                                       } catch (FileNotFoundException ff) {
+                                               total_log += ff.FusionLog;
+                                               continue;
+                                       }
+                               }
+                               if (!soft) {
+                                       Report.Error (6, "Cannot find assembly `" + assembly + "'" );
+                                       Console.WriteLine ("Log: \n" + total_log);
+                               }
+                       } catch (BadImageFormatException f) {
+                               Report.Error(6, "Cannot load assembly (bad file format)" + f.FusionLog);
+                       } catch (FileLoadException f){
+                               Report.Error(6, "Cannot load assembly " + f.FusionLog);
+                       } catch (ArgumentNullException){
+                               Report.Error(6, "Cannot load assembly (null argument)");
+                       }
+               }
+
+               static public void LoadModule (MethodInfo adder_method, string module)
+               {
+                       Module m;
+                       string total_log = "";
+
+                       try {
+                               try {
+                                       m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { module });
+                               }
+                               catch (TargetInvocationException ex) {
+                                       throw ex.InnerException;
+                               }
+                               TypeManager.AddModule (m);
+
+                       } 
+                       catch (FileNotFoundException){
+                               foreach (string dir in link_paths){
+                                       string full_path = Path.Combine (dir, module);
+                                       if (!module.EndsWith (".netmodule"))
+                                               full_path += ".netmodule";
+
+                                       try {
+                                               try {
+                                                       m = (Module)adder_method.Invoke (CodeGen.Assembly.Builder, new object [] { full_path });
+                                               }
+                                               catch (TargetInvocationException ex) {
+                                                       throw ex.InnerException;
+                                               }
+                                               TypeManager.AddModule (m);
+                                               return;
+                                       } catch (FileNotFoundException ff) {
+                                               total_log += ff.FusionLog;
+                                               continue;
+                                       }
+                               }
+                               Report.Error (6, "Cannot find module `" + module + "'" );
+                               Console.WriteLine ("Log: \n" + total_log);
+                       } catch (BadImageFormatException f) {
+                               Report.Error(6, "Cannot load module (bad file format)" + f.FusionLog);
+                       } catch (FileLoadException f){
+                               Report.Error(6, "Cannot load module " + f.FusionLog);
+                       } catch (ArgumentNullException){
+                               Report.Error(6, "Cannot load module (null argument)");
+                       }
+               }
+
+               /// <summary>
+               ///   Loads all assemblies referenced on the command line
+               /// </summary>
+               static public void LoadReferences ()
+               {
+                       foreach (string r in references)
+                               LoadAssembly (r, false);
+
+                       foreach (string r in soft_references)
+                               LoadAssembly (r, true);
+                       
+                       return;
+               }
+
+               static void SetupDefaultDefines ()
+               {
+                       defines = new ArrayList ();
+                       defines.Add ("__MonoCS__");
+               }
+
+               static string [] LoadArgs (string file)
+               {
+                       StreamReader f;
+                       ArrayList args = new ArrayList ();
+                       string line;
+                       try {
+                               f = new StreamReader (file);
+                       } catch {
+                               return null;
+                       }
+
+                       StringBuilder sb = new StringBuilder ();
+                       
+                       while ((line = f.ReadLine ()) != null){
+                               int t = line.Length;
+
+                               for (int i = 0; i < t; i++){
+                                       char c = line [i];
+                                       
+                                       if (c == '"' || c == '\''){
+                                               char end = c;
+                                               
+                                               for (i++; i < t; i++){
+                                                       c = line [i];
+
+                                                       if (c == end)
+                                                               break;
+                                                       sb.Append (c);
+                                               }
+                                       } else if (c == ' '){
+                                               if (sb.Length > 0){
+                                                       args.Add (sb.ToString ());
+                                                       sb.Length = 0;
+                                               }
+                                       } else
+                                               sb.Append (c);
+                               }
+                               if (sb.Length > 0){
+                                       args.Add (sb.ToString ());
+                                       sb.Length = 0;
+                               }
+                       }
+
+                       string [] ret_value = new string [args.Count];
+                       args.CopyTo (ret_value, 0);
+
+                       return ret_value;
+               }
+
+               //
+               // Returns the directory where the system assemblies are installed
+               //
+               static string GetSystemDir ()
+               {
+                       Assembly [] assemblies = AppDomain.CurrentDomain.GetAssemblies ();
+
+                       foreach (Assembly a in assemblies){
+                               string codebase = a.Location;
+                                string fn = System.IO.Path.GetFileName (codebase);
+                               if (fn == "corlib.dll" || fn == "mscorlib.dll"){
+                                       return codebase.Substring (0, codebase.LastIndexOf (System.IO.Path.DirectorySeparatorChar));
+                               }
+                       }
+
+                       Report.Error (-15, "Can not compute my system path");
+                       return "";
+               }
+
+               //
+               // Given a path specification, splits the path from the file/pattern
+               //
+               static void SplitPathAndPattern (string spec, out string path, out string pattern)
+               {
+                       int p = spec.LastIndexOf ('/');
+                       if (p != -1){
+                               //
+                               // Windows does not like /file.cs, switch that to:
+                               // "\", "file.cs"
+                               //
+                               if (p == 0){
+                                       path = "\\";
+                                       pattern = spec.Substring (1);
+                               } else {
+                                       path = spec.Substring (0, p);
+                                       pattern = spec.Substring (p + 1);
+                               }
+                               return;
+                       }
+
+                       p = spec.LastIndexOf ('\\');
+                       if (p != -1){
+                               path = spec.Substring (0, p);
+                               pattern = spec.Substring (p + 1);
+                               return;
+                       }
+
+                       path = ".";
+                       pattern = spec;
+               }
+
+               static void ProcessFile (string f)
+               {
+                       if (first_source == null)
+                               first_source = f;
+
+                       Location.AddFile (f);
+               }
+
+               static void ProcessFiles ()
+               {
+                       Location.Initialize ();
+
+                       foreach (SourceFile file in Location.SourceFiles) {
+                               if (tokenize) {
+                                       tokenize_file (file);
+                               } else {
+                                       parse (file);
+                               }
+                       }
+               }
+
+               static void CompileFiles (string spec, bool recurse)
+               {
+                       string path, pattern;
+
+                       SplitPathAndPattern (spec, out path, out pattern);
+                       if (pattern.IndexOf ('*') == -1){
+                               ProcessFile (spec);
+                               return;
+                       }
+
+                       string [] files = null;
+                       try {
+                               files = Directory.GetFiles (path, pattern);
+                       } catch (System.IO.DirectoryNotFoundException) {
+                               Report.Error (2001, "Source file `" + spec + "' could not be found");
+                               return;
+                       } catch (System.IO.IOException){
+                               Report.Error (2001, "Source file `" + spec + "' could not be found");
+                               return;
+                       }
+                       foreach (string f in files) {
+                               ProcessFile (f);
+                       }
+
+                       if (!recurse)
+                               return;
+                       
+                       string [] dirs = null;
+
+                       try {
+                               dirs = Directory.GetDirectories (path);
+                       } catch {
+                       }
+                       
+                       foreach (string d in dirs) {
+                                       
+                               // Don't include path in this string, as each
+                               // directory entry already does
+                               CompileFiles (d + "/" + pattern, true);
+                       }
+               }
+
+               static void DefineDefaultConfig ()
+               {
+                       //
+                       // For now the "default config" is harcoded into the compiler
+                       // we can move this outside later
+                       //
+                       string [] default_config = {
+                               "System",
+                               "System.Xml",
+                               "Microsoft.VisualBasic",
+#if false
+                               //
+                               // Is it worth pre-loading all this stuff?
+                               //
+                               "Accessibility",
+                               "System.Configuration.Install",
+                               "System.Data",
+                               "System.Design",
+                               "System.DirectoryServices",
+                               "System.Drawing.Design",
+                               "System.Drawing",
+                               "System.EnterpriseServices",
+                               "System.Management",
+                               "System.Messaging",
+                               "System.Runtime.Remoting",
+                               "System.Runtime.Serialization.Formatters.Soap",
+                               "System.Security",
+                               "System.ServiceProcess",
+                               "System.Web",
+                               "System.Web.RegularExpressions",
+                               "System.Web.Services",
+                               "System.Windows.Forms"
+#endif
+                       };
+                       
+                       int p = 0;
+                       foreach (string def in default_config)
+                               soft_references.Insert (p++, def);
+               }
+
+               static void SetOutputFile (string name)
+               {
+                       output_file = name;
+               }
+
+               static void SetWarningLevel (string s)
+               {
+                       int level = 0;
+
+                       try {
+                               level = Int32.Parse (s);
+                       } catch {
+                               Report.Error (
+                                       1900,
+                                       "--wlevel requires a value from 0 to 4");
+                               Environment.Exit (1);
+                       }
+                       if (level < 0 || level > 4){
+                               Report.Error (1900, "Warning level must be 0 to 4");
+                               Environment.Exit (1);
+                       }
+                       RootContext.WarningLevel = level;
+                       TestWarningConflict ();
+               }
+
+               static void TestWarningConflict ()
+               {
+                       if (RootContext.WarningLevel == 0 && Report.WarningsAreErrors) {
+                               Report.Error (1901, "Conflicting options specified: Warning level 0; Treat warnings as errors");
+                               Environment.Exit (1);
+                       }
+               }
+
+               static void SetupV2 ()
+               {
+                       RootContext.Version = LanguageVersion.Default;
+                       defines.Add ("__V2__");
+               }
+               
+               static void Version ()
+               {
+                       string version = Assembly.GetExecutingAssembly ().GetName ().Version.ToString ();
+                       Console.WriteLine ("Mono C# compiler version {0}", version);
+                       Environment.Exit (0);
+               }
+               
+               //
+               // Currently handles the Unix-like command line options, but will be
+               // deprecated in favor of the CSCParseOption, which will also handle the
+               // options that start with a dash in the future.
+               //
+               static bool UnixParseOption (string arg, ref string [] args, ref int i)
+               {
+                       switch (arg){
+                       case "-v":
+                               CSharpParser.yacc_verbose_flag++;
+                               return true;
+
+                       case "--version":
+                               Version ();
+                               return true;
+                               
+                       case "--parse":
+                               parse_only = true;
+                               return true;
+                               
+                       case "--main": case "-m":
+                               if ((i + 1) >= args.Length){
+                                       Usage ();
+                                       Environment.Exit (1);
+                               }
+                               RootContext.MainClass = args [++i];
+                               return true;
+                               
+                       case "--unsafe":
+                               RootContext.Unsafe = true;
+                               return true;
+                               
+                       case "/?": case "/h": case "/help":
+                       case "--help":
+                               Usage ();
+                               Environment.Exit (0);
+                               return true;
+                               
+                       case "--define":
+                               if ((i + 1) >= args.Length){
+                                       Usage ();
+                                       Environment.Exit (1);
+                               }
+                               defines.Add (args [++i]);
+                               return true;
+
+                       case "--show-counters":
+                               show_counters = true;
+                               return true;
+                               
+                       case "--expect-error": {
+                               int code = 0;
+                               
+                               try {
+                                       code = Int32.Parse (
+                                               args [++i], NumberStyles.AllowLeadingSign);
+                                       Report.ExpectedError = code;
+                               } catch {
+                                       Report.Error (-14, "Invalid number specified");
+                               } 
+                               return true;
+                       }
+                               
+                       case "--tokenize": 
+                               tokenize = true;
+                               return true;
+                               
+                       case "-o": 
+                       case "--output":
+                               if ((i + 1) >= args.Length){
+                                       Usage ();
+                                       Environment.Exit (1);
+                               }
+                               SetOutputFile (args [++i]);
+                               return true;
+                               
+                       case "--checked":
+                               RootContext.Checked = true;
+                               return true;
+                               
+                       case "--stacktrace":
+                               Report.Stacktrace = true;
+                               return true;
+                               
+                       case "--linkresource":
+                       case "--linkres":
+                               if ((i + 1) >= args.Length){
+                                       Usage ();
+                                       Report.Error (5, "Missing argument to --linkres"); 
+                                       Environment.Exit (1);
+                               }
+                               if (resources == null)
+                                       resources = new ArrayList ();
+                               
+                               resources.Add (args [++i]);
+                               return true;
+                               
+                       case "--resource":
+                       case "--res":
+                               if ((i + 1) >= args.Length){
+                                       Usage ();
+                                       Report.Error (5, "Missing argument to --resource"); 
+                                       Environment.Exit (1);
+                               }
+                               if (embedded_resources == null)
+                                       embedded_resources = new ArrayList ();
+                               
+                               embedded_resources.Add (args [++i]);
+                               return true;
+                               
+                       case "--target":
+                               if ((i + 1) >= args.Length){
+                                       Environment.Exit (1);
+                                       return true;
+                               }
+                               
+                               string type = args [++i];
+                               switch (type){
+                               case "library":
+                                       RootContext.Target = Target.Library;
+                                       RootContext.TargetExt = ".dll";
+                                       break;
+                                       
+                               case "exe":
+                                       RootContext.Target = Target.Exe;
+                                       break;
+                                       
+                               case "winexe":
+                                       RootContext.Target = Target.WinExe;
+                                       break;
+                                       
+                               case "module":
+                                       RootContext.Target = Target.Module;
+                                       RootContext.TargetExt = ".dll";
+                                       break;
+                               default:
+                                       TargetUsage ();
+                                       Environment.Exit (1);
+                                       break;
+                               }
+                               return true;
+                               
+                       case "-r":
+                               if ((i + 1) >= args.Length){
+                                       Usage ();
+                                       Environment.Exit (1);
+                               }
+                               
+                               references.Add (args [++i]);
+                               return true;
+                               
+                       case "-L":
+                               if ((i + 1) >= args.Length){
+                                       Usage ();       
+                                       Environment.Exit (1);
+                               }
+                               link_paths.Add (args [++i]);
+                               return true;
+                               
+                       case "--nostdlib":
+                               RootContext.StdLib = false;
+                               return true;
+                               
+                       case "--fatal":
+                               Report.Fatal = true;
+                               return true;
+                               
+                       case "--werror":
+                               Report.WarningsAreErrors = true;
+                               TestWarningConflict();
+                               return true;
+                               
+                       case "--nowarn":
+                               if ((i + 1) >= args.Length){
+                                       Usage ();
+                                       Environment.Exit (1);
+                               }
+                               int warn = 0;
+                               
+                               try {
+                                       warn = Int32.Parse (args [++i]);
+                               } catch {
+                                       Usage ();
+                                       Environment.Exit (1);
+                               }
+                               Report.SetIgnoreWarning (warn);
+                               return true;
+                               
+                       case "--wlevel":
+                               if ((i + 1) >= args.Length){
+                                       Report.Error (
+                                               1900,
+                                               "--wlevel requires a value from 0 to 4");
+                                       Environment.Exit (1);
+                               }
+
+                               SetWarningLevel (args [++i]);
+                               return true;
+
+                       case "--mcs-debug":
+                               if ((i + 1) >= args.Length){
+                                       Report.Error (5, "--mcs-debug requires an argument");
+                                       Environment.Exit (1);
+                               }
+
+                               try {
+                                       Report.DebugFlags = Int32.Parse (args [++i]);
+                               } catch {
+                                       Report.Error (5, "Invalid argument to --mcs-debug");
+                                       Environment.Exit (1);
+                               }
+                               return true;
+                               
+                       case "--about":
+                               About ();
+                               return true;
+                               
+                       case "--recurse":
+                               if ((i + 1) >= args.Length){
+                                       Report.Error (5, "--recurse requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               CompileFiles (args [++i], true); 
+                               return true;
+                               
+                       case "--timestamp":
+                               timestamps = true;
+                               last_time = first_time = DateTime.Now;
+                               return true;
+
+                       case "--pause":
+                               pause = true;
+                               return true;
+                               
+                       case "--debug": case "-g":
+                               want_debugging_support = true;
+                               return true;
+                               
+                       case "--noconfig":
+                               load_default_config = false;
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               //
+               // Currently it is very basic option parsing, but eventually, this will
+               // be the complete option parser
+               //
+               static bool CSCParseOption (string option, ref string [] args, ref int i)
+               {
+                       int idx = option.IndexOf (':');
+                       string arg, value;
+
+                       if (idx == -1){
+                               arg = option;
+                               value = "";
+                       } else {
+                               arg = option.Substring (0, idx);
+
+                               value = option.Substring (idx + 1);
+                       }
+
+                       switch (arg){
+                       case "/nologo":
+                               return true;
+
+                       case "/t":
+                       case "/target":
+                               switch (value){
+                               case "exe":
+                                       RootContext.Target = Target.Exe;
+                                       break;
+
+                               case "winexe":
+                                       RootContext.Target = Target.WinExe;
+                                       break;
+
+                               case "library":
+                                       RootContext.Target = Target.Library;
+                                       RootContext.TargetExt = ".dll";
+                                       break;
+
+                               case "module":
+                                       RootContext.Target = Target.Module;
+                                       RootContext.TargetExt = ".netmodule";
+                                       break;
+
+                               default:
+                                       TargetUsage ();
+                                       Environment.Exit (1);
+                                       break;
+                               }
+                               return true;
+
+                       case "/out":
+                               if (value == ""){
+                                       Usage ();
+                                       Environment.Exit (1);
+                               }
+                               SetOutputFile (value);
+                               return true;
+
+                       case "/optimize":
+                       case "/optimize+":
+                       case "/optimize-":
+                       case "/incremental":
+                       case "/incremental+":
+                       case "/incremental-":
+                               // nothing.
+                               return true;
+
+                       case "/d":
+                       case "/define": {
+                               string [] defs;
+
+                               if (value == ""){
+                                       Usage ();
+                                       Environment.Exit (1);
+                               }
+
+                               defs = value.Split (new Char [] {';', ','});
+                               foreach (string d in defs){
+                                       defines.Add (d);
+                               }
+                               return true;
+                       }
+
+                       case "/linkres":
+                       case "/linkresource":
+                               if (value == ""){
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               if (resources == null)
+                                       resources = new ArrayList ();
+                               
+                               resources.Add (value);
+                               return true;
+                               
+                       case "/pkg": {
+                               string packages;
+
+                               if (value == ""){
+                                       Usage ();
+                                       Environment.Exit (1);
+                               }
+                               packages = String.Join (" ", value.Split (new Char [] { ';', ',', '\n', '\r'}));
+                               
+                               ProcessStartInfo pi = new ProcessStartInfo ();
+                               pi.FileName = "pkg-config";
+                               pi.RedirectStandardOutput = true;
+                               pi.UseShellExecute = false;
+                               pi.Arguments = "--libs " + packages;
+                               Process p = null;
+                               try {
+                                       p = Process.Start (pi);
+                               } catch (Exception e) {
+                                       Report.Error (-27, "Couldn't run pkg-config: " + e.Message);
+                                       Environment.Exit (1);
+                               }
+
+                               if (p.StandardOutput == null){
+                                       Report.Warning (-27, "Specified package did not return any information");
+                                       return true;
+                               }
+                               string pkgout = p.StandardOutput.ReadToEnd ();
+                               p.WaitForExit ();
+                               if (p.ExitCode != 0) {
+                                       Report.Error (-27, "Error running pkg-config. Check the above output.");
+                                       Environment.Exit (1);
+                               }
+
+                               if (pkgout != null){
+                                       string [] xargs = pkgout.Trim (new Char [] {' ', '\n', '\r', '\t'}).
+                                               Split (new Char [] { ' ', '\t'});
+                                       args = AddArgs (args, xargs);
+                               }
+                               
+                               p.Close ();
+                               return true;
+                       }
+                               
+                       case "/res":
+                       case "/resource":
+                               if (value == ""){
+                                       Report.Error (5, "-resource requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               if (embedded_resources == null)
+                                       embedded_resources = new ArrayList ();
+                               
+                               if (embedded_resources.Contains (value)) {
+                                       Report.Error (1508, String.Format ("The resource identifier '{0}' has already been used in this assembly.", value));
+                               }
+                               else if (value.IndexOf (',') != -1 && embedded_resources.Contains (value.Split (',')[1])) {
+                                       Report.Error (1508, String.Format ("The resource identifier '{0}' has already been used in this assembly.", value));
+                               }
+                               else {
+                               embedded_resources.Add (value);
+                               }
+                               return true;
+                               
+                       case "/recurse":
+                               if (value == ""){
+                                       Report.Error (5, "-recurse requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               CompileFiles (value, true); 
+                               return true;
+
+                       case "/r":
+                       case "/reference": {
+                               if (value == ""){
+                                       Report.Error (5, "-reference requires an argument");
+                                       Environment.Exit (1);
+                               }
+
+                               string [] refs = value.Split (new char [] { ';', ',' });
+                               foreach (string r in refs){
+                                       references.Add (r);
+                               }
+                               return true;
+                       }
+                       case "/addmodule": {
+                               if (value == ""){
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+
+                               string [] refs = value.Split (new char [] { ';', ',' });
+                               foreach (string r in refs){
+                                       modules.Add (r);
+                               }
+                               return true;
+                       }
+                       case "/win32res": {
+                               if (value == "") {
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+
+                               win32ResourceFile = value;
+                               return true;
+                       }
+                       case "/win32icon": {
+                               if (value == "") {
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+
+                               win32IconFile = value;
+                               return true;
+                       }
+                       case "/doc": {
+                               if (value == ""){
+                                       Report.Error (2006, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               RootContext.Documentation = new Documentation (value);
+                               return true;
+                       }
+                       case "/lib": {
+                               string [] libdirs;
+                               
+                               if (value == ""){
+                                       Report.Error (5, "/lib requires an argument");
+                                       Environment.Exit (1);
+                               }
+
+                               libdirs = value.Split (new Char [] { ',' });
+                               foreach (string dir in libdirs)
+                                       link_paths.Add (dir);
+                               return true;
+                       }
+
+                       case "/debug-":
+                               want_debugging_support = false;
+                               return true;
+                               
+                       case "/debug":
+                       case "/debug+":
+                               want_debugging_support = true;
+                               return true;
+
+                       case "/checked":
+                       case "/checked+":
+                               RootContext.Checked = true;
+                               return true;
+
+                       case "/checked-":
+                               RootContext.Checked = false;
+                               return true;
+
+                       case "/clscheck":
+                       case "/clscheck+":
+                               return true;
+
+                       case "/clscheck-":
+                               RootContext.VerifyClsCompliance = false;
+                               return true;
+
+                       case "/unsafe":
+                       case "/unsafe+":
+                               RootContext.Unsafe = true;
+                               return true;
+
+                       case "/unsafe-":
+                               RootContext.Unsafe = false;
+                               return true;
+
+                       case "/warnaserror":
+                       case "/warnaserror+":
+                               Report.WarningsAreErrors = true;
+                               TestWarningConflict();
+                               return true;
+
+                       case "/warnaserror-":
+                               Report.WarningsAreErrors = false;
+                               return true;
+
+                       case "/warn":
+                               SetWarningLevel (value);
+                               return true;
+
+                       case "/nowarn": {
+                               string [] warns;
+
+                               if (value == ""){
+                                       Report.Error (5, "/nowarn requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               
+                               warns = value.Split (new Char [] {','});
+                               foreach (string wc in warns){
+                                       try {
+                                               int warn = Int32.Parse (wc);
+                                               if (warn < 1) {
+                                                       throw new ArgumentOutOfRangeException("warn");
+                                               }
+                                               Report.SetIgnoreWarning (warn);
+                                       } catch {
+                                               Report.Error (1904, String.Format("'{0}' is not a valid warning number", wc));
+                                               Environment.Exit (1);
+                                       }
+                               }
+                               return true;
+                       }
+
+                       case "/noconfig-":
+                               load_default_config = true;
+                               return true;
+                               
+                       case "/noconfig":
+                       case "/noconfig+":
+                               load_default_config = false;
+                               return true;
+
+                       case "/help2":
+                               OtherFlags ();
+                               Environment.Exit(0);
+                               return true;
+                               
+                       case "/help":
+                       case "/?":
+                               Usage ();
+                               Environment.Exit (0);
+                               return true;
+
+                       case "/main":
+                       case "/m":
+                               if (value == ""){
+                                       Report.Error (5, arg + " requires an argument");                                        
+                                       Environment.Exit (1);
+                               }
+                               RootContext.MainClass = value;
+                               return true;
+
+                       case "/nostdlib":
+                       case "/nostdlib+":
+                               RootContext.StdLib = false;
+                               return true;
+
+                       case "/nostdlib-":
+                               RootContext.StdLib = true;
+                               return true;
+
+                       case "/fullpaths":
+                               return true;
+
+                       case "/keyfile":
+                               if (value == String.Empty) {
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               RootContext.StrongNameKeyFile = value;
+                               return true;
+                       case "/keycontainer":
+                               if (value == String.Empty) {
+                                       Report.Error (5, arg + " requires an argument");
+                                       Environment.Exit (1);
+                               }
+                               RootContext.StrongNameKeyContainer = value;
+                               return true;
+                       case "/delaysign+":
+                               RootContext.StrongNameDelaySign = true;
+                               return true;
+                       case "/delaysign-":
+                               RootContext.StrongNameDelaySign = false;
+                               return true;
+
+                       case "/v2":
+                       case "/2":
+                               Console.WriteLine ("The compiler option -2 is obsolete. Please use /langversion instead");
+                               SetupV2 ();
+                               return true;
+                               
+                       case "/langversion":
+                               switch (value.ToLower (CultureInfo.InvariantCulture)) {
+                                       case "iso-1":
+                                               RootContext.Version = LanguageVersion.ISO_1;
+                                               return true;
+
+                                       case "default":
+                                               SetupV2 ();
+                                               return true;
+                               }
+                               Report.Error (1617, "Invalid option '{0}' for /langversion; must be ISO-1 or Default", value);
+                               Environment.Exit (1);
+                               return false;
+
+                       case "/codepage":
+                               int cp = -1;
+
+                               if (value == "utf8"){
+                                       encoding = new UTF8Encoding();
+                                       using_default_encoder = false;
+                                       return true;
+                               }
+                               if (value == "reset"){
+                                       //
+                                       // 28591 is the code page for ISO-8859-1 encoding.
+                                       //
+                                       cp = 28591;
+                                       using_default_encoder = true;
+                               }
+                               
+                               try {
+                                       cp = Int32.Parse (value);
+                                       encoding = Encoding.GetEncoding (cp);
+                                       using_default_encoder = false;
+                               } catch {
+                                       Report.Error (2016, String.Format("Code page '{0}' is invalid or not installed", cp));
+                                       Environment.Exit (1);
+                               }
+                               return true;
+                       }
+                       //Report.Error (2007, String.Format ("Unrecognized command-line option: '{0}'", option));
+                       //Environment.Exit (1);
+                       return false;
+               }
+               
+               static string [] AddArgs (string [] args, string [] extra_args)
+               {
+                       string [] new_args;
+
+                       new_args = new string [extra_args.Length + args.Length];
+                       args.CopyTo (new_args, 0);
+                       extra_args.CopyTo (new_args, args.Length);
+
+                       return new_args;
+               }
+               
+               /// <summary>
+               ///    Parses the arguments, and drives the compilation
+               ///    process.
+               /// </summary>
+               ///
+               /// <remarks>
+               ///    TODO: Mostly structured to debug the compiler
+               ///    now, needs to be turned into a real driver soon.
+               /// </remarks>
+               // [MonoTODO("Change error code for unknown argument to something reasonable")]
+               internal static bool MainDriver (string [] args)
+               {
+                       int i;
+                       bool parsing_options = true;
+
+                       try {
+                               encoding = Encoding.GetEncoding (28591);
+                       } catch {
+                               Console.WriteLine ("Error: could not load encoding 28591, trying 1252");
+                               encoding = Encoding.GetEncoding (1252);
+                       }
+                       
+                       references = new ArrayList ();
+                       soft_references = new ArrayList ();
+                       modules = new ArrayList ();
+                       link_paths = new ArrayList ();
+
+                       SetupDefaultDefines ();
+                       
+                       //
+                       // Setup defaults
+                       //
+                       // This is not required because Assembly.Load knows about this
+                       // path.
+                       //
+
+                       for (i = 0; i < args.Length; i++){
+                               string arg = args [i];
+                               if (arg == "")
+                                       continue;
+
+                               if (arg.StartsWith ("@")){
+                                       string [] extra_args;
+                                       string response_file = arg.Substring (1);
+
+                                       if (response_file_list == null)
+                                               response_file_list = new Hashtable ();
+                                       
+                                       if (response_file_list.Contains (response_file)){
+                                               Report.Error (
+                                                       1515, "Response file `" + response_file +
+                                                       "' specified multiple times");
+                                               Environment.Exit (1);
+                                       }
+                                       
+                                       response_file_list.Add (response_file, response_file);
+                                                   
+                                       extra_args = LoadArgs (response_file);
+                                       if (extra_args == null){
+                                               Report.Error (2011, "Unable to open response file: " +
+                                                             response_file);
+                                               return false;
+                                       }
+
+                                       args = AddArgs (args, extra_args);
+                                       continue;
+                               }
+
+                               if (parsing_options){
+                                       if (arg == "--"){
+                                               parsing_options = false;
+                                               continue;
+                                       }
+                                       
+                                       if (arg.StartsWith ("-")){
+                                               if (UnixParseOption (arg, ref args, ref i))
+                                                       continue;
+
+                                               // Try a -CSCOPTION
+                                               string csc_opt = "/" + arg.Substring (1);
+                                               if (CSCParseOption (csc_opt, ref args, ref i))
+                                                       continue;
+                                       } else {
+                                               if (arg.StartsWith ("/")){
+                                                       if (CSCParseOption (arg, ref args, ref i))
+                                                               continue;
+                                               }
+                                       }
+                               }
+
+                               CompileFiles (arg, false); 
+                       }
+
+                       ProcessFiles ();
+
+                       if (tokenize)
+                               return true;
+                       
+                       //
+                       // If we are an exe, require a source file for the entry point
+                       //
+                       if (RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe){
+                       if (first_source == null){
+                               Report.Error (2008, "No files to compile were specified");
+                               return false;
+                       }
+
+                       }
+
+                       //
+                       // If there is nothing to put in the assembly, and we are not a library
+                       //
+                       if (first_source == null && embedded_resources == null && resources == null){
+                                       Report.Error (2008, "No files to compile were specified");
+                                       return false;
+                       }
+
+                       if (Report.Errors > 0)
+                               return false;
+                       
+                       if (parse_only)
+                               return true;
+                       
+                       Tokenizer.Cleanup ();
+                       
+                       //
+                       // Load Core Library for default compilation
+                       //
+                       if (RootContext.StdLib) 
+                               references.Insert (0, "mscorlib");
+
+                       if (load_default_config)
+                               DefineDefaultConfig ();
+
+                       if (Report.Errors > 0){
+                               return false;
+                       }
+
+                       //
+                       // Load assemblies required
+                       //
+                       if (timestamps)
+                               ShowTime ("Loading references");
+                       link_paths.Add (GetSystemDir ());
+                       link_paths.Add (Directory.GetCurrentDirectory ());
+                       LoadReferences ();
+                       
+                       if (timestamps)
+                               ShowTime ("   References loaded");
+                       
+                       if (Report.Errors > 0){
+                               return false;
+                       }
+
+                       //
+                       // Quick hack
+                       //
+                       if (output_file == null){
+                               int pos = first_source.LastIndexOf ('.');
+
+                               if (pos > 0)
+                                       output_file = first_source.Substring (0, pos) + RootContext.TargetExt;
+                               else
+                                       output_file = first_source + RootContext.TargetExt;
+                       }
+
+                       CodeGen.Init (output_file, output_file, want_debugging_support);
+
+                       if (RootContext.Target == Target.Module) {
+                               PropertyInfo module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+                               if (module_only == null) {
+                                       Report.Error (0, new Location (-1), "Cannot use /target:module on this runtime: try the Mono runtime instead.");
+                                       Environment.Exit (1);
+                               }
+
+                               MethodInfo set_method = module_only.GetSetMethod (true);
+                               set_method.Invoke (CodeGen.Assembly.Builder, BindingFlags.Default, null, new object[]{true}, null);
+                       }
+
+                       TypeManager.AddModule (CodeGen.Module.Builder);
+
+                       if (modules.Count > 0) {
+                               MethodInfo adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance|BindingFlags.NonPublic);
+                               if (adder_method == null) {
+                                       Report.Error (0, new Location (-1), "Cannot use /addmodule on this runtime: Try the Mono runtime instead.");
+                                       Environment.Exit (1);
+                               }
+
+                               foreach (string module in modules)
+                                       LoadModule (adder_method, module);
+                       }
+
+                       TypeManager.ComputeNamespaces ();
+                       
+                       //
+                       // Before emitting, we need to get the core
+                       // types emitted from the user defined types
+                       // or from the system ones.
+                       //
+                       if (timestamps)
+                               ShowTime ("Initializing Core Types");
+                       if (!RootContext.StdLib){
+                               RootContext.ResolveCore ();
+                               if (Report.Errors > 0)
+                                       return false;
+                       }
+                       
+                       TypeManager.InitCoreTypes ();
+                       if (timestamps)
+                               ShowTime ("   Core Types done");
+
+                       //
+                       // The second pass of the compiler
+                       //
+                       if (timestamps)
+                               ShowTime ("Resolving tree");
+                       RootContext.ResolveTree ();
+
+                       if (Report.Errors > 0)
+                               return false;
+                       if (timestamps)
+                               ShowTime ("Populate tree");
+                       if (!RootContext.StdLib)
+                               RootContext.BootCorlib_PopulateCoreTypes ();
+                       RootContext.PopulateTypes ();
+                       RootContext.DefineTypes ();
+                       
+                       if (RootContext.Documentation != null &&
+                               !RootContext.Documentation.OutputDocComment (
+                                       output_file))
+                               return false;
+
+                       TypeManager.InitCodeHelpers ();
+
+                       //
+                       // Verify using aliases now
+                       //
+                       Namespace.VerifyUsing ();
+                       
+                       if (Report.Errors > 0){
+                               return false;
+                       }
+                       
+                       if (RootContext.VerifyClsCompliance) { 
+                               CodeGen.Assembly.ResolveClsCompliance ();
+                               if (CodeGen.Assembly.IsClsCompliant) {
+                               AttributeTester.VerifyModulesClsCompliance ();
+                               TypeManager.LoadAllImportedTypes ();
+                                       AttributeTester.VerifyTopLevelNameClsCompliance ();
+                               }
+                       }
+                       
+                       //
+                       // The code generator
+                       //
+                       if (timestamps)
+                               ShowTime ("Emitting code");
+                       ShowTotalTime ("Total so far");
+                       RootContext.EmitCode ();
+                       if (timestamps)
+                               ShowTime ("   done");
+
+                       if (Report.Errors > 0){
+                               return false;
+                       }
+
+                       if (timestamps)
+                               ShowTime ("Closing types");
+
+                       RootContext.CloseTypes ();
+
+                       PEFileKinds k = PEFileKinds.ConsoleApplication;
+                               
+                       switch (RootContext.Target) {
+                       case Target.Library:
+                       case Target.Module:
+                               k = PEFileKinds.Dll; break;
+                       case Target.Exe:
+                               k = PEFileKinds.ConsoleApplication; break;
+                       case Target.WinExe:
+                               k = PEFileKinds.WindowApplication; break;
+                       }
+
+                       if (RootContext.NeedsEntryPoint) {
+                               MethodInfo ep = RootContext.EntryPoint;
+
+                               if (ep == null) {
+                                       if (RootContext.MainClass != null) {
+                                               object main_cont = RootContext.Tree.Decls [RootContext.MainClass];
+                                               if (main_cont == null) {
+                                                       Report.Error (1555, output_file, "Could not find '{0}' specified for Main method", RootContext.MainClass); 
+                                                       return false;
+                                               }
+
+                                               if (!(main_cont is ClassOrStruct)) {
+                                                       Report.Error (1556, output_file, "'{0}' specified for Main method must be a valid class or struct", RootContext.MainClass);
+                                                       return false;
+                                               }
+                                       }
+
+                                       if (Report.Errors == 0)
+                                               Report.Error (5001, "Program " + output_file +
+                                                             " does not have an entry point defined");
+                                       return false;
+                               }
+                               
+                               CodeGen.Assembly.Builder.SetEntryPoint (ep, k);
+                       } else if (RootContext.MainClass != null) {
+                               Report.Error (2017, "Can not specify -main: when building module or library");
+                       }
+
+                       //
+                       // Add the resources
+                       //
+                       if (resources != null){
+                               foreach (string spec in resources){
+                                       string file, res;
+                                       int cp;
+                                       
+                                       cp = spec.IndexOf (',');
+                                       if (cp != -1){
+                                               file = spec.Substring (0, cp);
+                                               res = spec.Substring (cp + 1);
+                                       } else
+                                               file = res = spec;
+
+                                       CodeGen.Assembly.Builder.AddResourceFile (res, file);
+                               }
+                       }
+                       
+                       if (embedded_resources != null){
+                               object[] margs = new object [2];
+                               Type[] argst = new Type [2];
+                               argst [0] = argst [1] = typeof (string);
+
+                               MethodInfo embed_res = typeof (AssemblyBuilder).GetMethod (
+                                       "EmbedResourceFile", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic,
+                                       null, CallingConventions.Any, argst, null);
+                               
+                               if (embed_res == null) {
+                                       Report.Warning (0, new Location (-1),
+                                                       "Cannot embed resources on this runtime: try the Mono runtime instead.");
+                               } else {
+                                       foreach (string spec in embedded_resources) {
+                                               int cp;
+
+                                               cp = spec.IndexOf (',');
+                                               if (cp != -1){
+                                                       margs [0] = spec.Substring (cp + 1);
+                                                       margs [1] = spec.Substring (0, cp);
+                                               } else {
+                                                       margs [1] = spec;
+                                                       margs [0] = Path.GetFileName (spec);
+                                               }
+
+                                               if (File.Exists ((string) margs [1]))
+                                                       embed_res.Invoke (CodeGen.Assembly.Builder, margs);
+                                               else {
+                                                       Report.Error (1566, "Can not find the resource " + margs [1]);
+                                               }
+                                       }
+                               }
+                       }
+
+                       //
+                       // Add Win32 resources
+                       //
+
+                       CodeGen.Assembly.Builder.DefineVersionInfoResource ();
+
+                       if (win32ResourceFile != null) {
+                               try {
+                                       CodeGen.Assembly.Builder.DefineUnmanagedResource (win32ResourceFile);
+                               }
+                               catch (ArgumentException) {
+                                       Report.Warning (0, new Location (-1), "Cannot embed win32 resources on this runtime: try the Mono runtime instead.");
+                               }
+                       }
+
+                       if (win32IconFile != null) {
+                               MethodInfo define_icon = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance|BindingFlags.Public|BindingFlags.NonPublic);
+                               if (define_icon == null) {
+                                       Report.Warning (0, new Location (-1), "Cannot embed icon resource on this runtime: try the Mono runtime instead.");
+                               }
+                               define_icon.Invoke (CodeGen.Assembly.Builder, new object [] { win32IconFile });
+                       }
+
+                       if (Report.Errors > 0)
+                               return false;
+                       
+                       CodeGen.Save (output_file);
+                       if (timestamps) {
+                               ShowTime ("Saved output");
+                               ShowTotalTime ("Total");
+                       }
+
+                       Timer.ShowTimers ();
+                       
+                       if (Report.ExpectedError != 0){
+                               if (Report.Errors == 0) {
+                                       Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" +
+                                               "No other errors reported.");
+                                       
+                                       Environment.Exit (2);
+                               } else {
+                                       Console.WriteLine ("Failed to report expected error " + Report.ExpectedError + ".\n" +
+                                               "However, other errors were reported.");
+                                       
+                               Environment.Exit (1);
+                               }
+                               
+                               
+                               return false;
+                       }
+
+#if DEBUGME
+                       Console.WriteLine ("Size of strings held: " + DeclSpace.length);
+                       Console.WriteLine ("Size of strings short: " + DeclSpace.small);
+#endif
+                       return (Report.Errors == 0);
+               }
+       }
+
+       //
+       // This is the only public entry point
+       //
+       public class CompilerCallableEntryPoint : MarshalByRefObject {
+               static bool used = false;
+               
+               public bool InvokeCompiler (string [] args)
+               {
+                       if (used)
+                               Reset ();
+                       bool ok = Driver.MainDriver (args);
+                       return ok && Report.Errors == 0;
+               }
+
+               public void Reset ()
+               {
+               }
+       }
+}
diff --git a/mcs/bmcs/ecore.cs b/mcs/bmcs/ecore.cs
new file mode 100644 (file)
index 0000000..87e2815
--- /dev/null
@@ -0,0 +1,3748 @@
+//
+// ecore.cs: Core of the Expression representation for the intermediate tree.
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001, 2002, 2003 Ximian, Inc.
+//
+//
+
+namespace Mono.CSharp {
+       using System;
+       using System.Collections;
+       using System.Diagnostics;
+       using System.Reflection;
+       using System.Reflection.Emit;
+       using System.Text;
+
+       /// <remarks>
+       ///   The ExprClass class contains the is used to pass the 
+       ///   classification of an expression (value, variable, namespace,
+       ///   type, method group, property access, event access, indexer access,
+       ///   nothing).
+       /// </remarks>
+       public enum ExprClass : byte {
+               Invalid,
+               
+               Value,
+               Variable,
+               Namespace,
+               Type,
+               MethodGroup,
+               PropertyAccess,
+               EventAccess,
+               IndexerAccess,
+               Nothing, 
+       }
+
+       /// <remarks>
+       ///   This is used to tell Resolve in which types of expressions we're
+       ///   interested.
+       /// </remarks>
+       [Flags]
+       public enum ResolveFlags {
+               // Returns Value, Variable, PropertyAccess, EventAccess or IndexerAccess.
+               VariableOrValue         = 1,
+
+               // Returns a type expression.
+               Type                    = 2,
+
+               // Returns a method group.
+               MethodGroup             = 4,
+
+               // Allows SimpleNames to be returned.
+               // This is used by MemberAccess to construct long names that can not be
+               // partially resolved (namespace-qualified names for example).
+               SimpleName              = 8,
+
+               // Mask of all the expression class flags.
+               MaskExprClass           = 15,
+
+               // Disable control flow analysis while resolving the expression.
+               // This is used when resolving the instance expression of a field expression.
+               DisableFlowAnalysis     = 16,
+
+               // Set if this is resolving the first part of a MemberAccess.
+               Intermediate            = 32
+       }
+
+       //
+       // This is just as a hint to AddressOf of what will be done with the
+       // address.
+       [Flags]
+       public enum AddressOp {
+               Store = 1,
+               Load  = 2,
+               LoadStore = 3
+       };
+       
+       /// <summary>
+       ///   This interface is implemented by variables
+       /// </summary>
+       public interface IMemoryLocation {
+               /// <summary>
+               ///   The AddressOf method should generate code that loads
+               ///   the address of the object and leaves it on the stack.
+               ///
+               ///   The `mode' argument is used to notify the expression
+               ///   of whether this will be used to read from the address or
+               ///   write to the address.
+               ///
+               ///   This is just a hint that can be used to provide good error
+               ///   reporting, and should have no other side effects. 
+               /// </summary>
+               void AddressOf (EmitContext ec, AddressOp mode);
+       }
+
+       /// <summary>
+       ///   We are either a namespace or a type.
+       ///   If we're a type, `IsType' is true and we may use `Type' to get
+       ///   a TypeExpr representing that type.
+       /// </summary>
+       public interface IAlias {
+               bool IsType {
+                       get;
+               }
+
+               string Name {
+                       get;
+               }
+
+               TypeExpr ResolveAsType (EmitContext ec);
+       }
+
+       /// <summary>
+       ///   This interface is implemented by variables
+       /// </summary>
+       public interface IVariable {
+               VariableInfo VariableInfo {
+                       get;
+               }
+
+               bool VerifyFixed (bool is_expression);
+       }
+
+       /// <summary>
+       ///   This interface denotes an expression which evaluates to a member
+       ///   of a struct or a class.
+       /// </summary>
+       public interface IMemberExpr
+       {
+               /// <summary>
+               ///   The name of this member.
+               /// </summary>
+               string Name {
+                       get;
+               }
+
+               /// <summary>
+               ///   Whether this is an instance member.
+               /// </summary>
+               bool IsInstance {
+                       get;
+               }
+
+               /// <summary>
+               ///   Whether this is a static member.
+               /// </summary>
+               bool IsStatic {
+                       get;
+               }
+
+               /// <summary>
+               ///   The type which declares this member.
+               /// </summary>
+               Type DeclaringType {
+                       get;
+               }
+
+               /// <summary>
+               ///   The instance expression associated with this member, if it's a
+               ///   non-static member.
+               /// </summary>
+               Expression InstanceExpression {
+                       get; set;
+               }
+       }
+
+       /// <remarks>
+       ///   Base class for expressions
+       /// </remarks>
+       public abstract class Expression {
+               public ExprClass eclass;
+               protected Type type;
+               protected Location loc;
+               
+               public Type Type {
+                       get {
+                               return type;
+                       }
+
+                       set {
+                               type = value;
+                       }
+               }
+
+               public Location Location {
+                       get {
+                               return loc;
+                       }
+               }
+
+               /// <summary>
+               ///   Utility wrapper routine for Error, just to beautify the code
+               /// </summary>
+               public void Error (int error, string s)
+               {
+                       if (!Location.IsNull (loc))
+                               Report.Error (error, loc, s);
+                       else
+                               Report.Error (error, s);
+               }
+
+               /// <summary>
+               ///   Utility wrapper routine for Warning, just to beautify the code
+               /// </summary>
+               public void Warning (int code, string format, params object[] args)
+               {
+                       Report.Warning (code, loc, format, args);
+               }
+
+               // Not nice but we have broken hierarchy
+               public virtual void CheckMarshallByRefAccess (Type container) {}
+
+               /// <summary>
+               /// Tests presence of ObsoleteAttribute and report proper error
+               /// </summary>
+               protected void CheckObsoleteAttribute (Type type)
+               {
+                       ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (type);
+                       if (obsolete_attr == null)
+                               return;
+
+                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, type.FullName, loc);
+               }
+
+               public static bool IsAccessorAccessible (Type invocation_type, MethodInfo mi, out bool must_do_cs1540_check)
+               {
+                       MethodAttributes ma = mi.Attributes & MethodAttributes.MemberAccessMask;
+
+                       must_do_cs1540_check = false; // by default we do not check for this
+
+                       //
+                       // If only accessible to the current class or children
+                       //
+                       if (ma == MethodAttributes.Private) {
+                               Type declaring_type = mi.DeclaringType;
+                                       
+                               if (invocation_type != declaring_type)
+                                       return TypeManager.IsNestedFamilyAccessible (invocation_type, declaring_type);
+
+                               return true;
+                       }
+                       //
+                       // FamAndAssem requires that we not only derivate, but we are on the
+                       // same assembly.  
+                       //
+                       if (ma == MethodAttributes.FamANDAssem){
+                               return (mi.DeclaringType.Assembly != invocation_type.Assembly);
+                       }
+
+                       // Assembly and FamORAssem succeed if we're in the same assembly.
+                       if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
+                               if (mi.DeclaringType.Assembly == invocation_type.Assembly)
+                                       return true;
+                       }
+
+                       // We already know that we aren't in the same assembly.
+                       if (ma == MethodAttributes.Assembly)
+                               return false;
+
+                       // Family and FamANDAssem require that we derive.
+                       if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem) || (ma == MethodAttributes.FamORAssem)){
+                               if (!TypeManager.IsNestedFamilyAccessible (invocation_type, mi.DeclaringType))
+                                       return false;
+
+                               if (!TypeManager.IsNestedChildOf (invocation_type, mi.DeclaringType))
+                                       must_do_cs1540_check = true;
+
+                               return true;
+                       }
+
+                       return true;
+               }
+
+               /// <summary>
+               ///   Performs semantic analysis on the Expression
+               /// </summary>
+               ///
+               /// <remarks>
+               ///   The Resolve method is invoked to perform the semantic analysis
+               ///   on the node.
+               ///
+               ///   The return value is an expression (it can be the
+               ///   same expression in some cases) or a new
+               ///   expression that better represents this node.
+               ///   
+               ///   For example, optimizations of Unary (LiteralInt)
+               ///   would return a new LiteralInt with a negated
+               ///   value.
+               ///   
+               ///   If there is an error during semantic analysis,
+               ///   then an error should be reported (using Report)
+               ///   and a null value should be returned.
+               ///   
+               ///   There are two side effects expected from calling
+               ///   Resolve(): the the field variable "eclass" should
+               ///   be set to any value of the enumeration
+               ///   `ExprClass' and the type variable should be set
+               ///   to a valid type (this is the type of the
+               ///   expression).
+               /// </remarks>
+               public abstract Expression DoResolve (EmitContext ec);
+
+               public virtual Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       return DoResolve (ec);
+               }
+
+               //
+               // This is used if the expression should be resolved as a type.
+               // the default implementation fails.   Use this method in
+               // those participants in the SimpleName chain system.
+               //
+               public virtual Expression ResolveAsTypeStep (EmitContext ec)
+               {
+                       return null;
+               }
+
+               //
+               // This is used to resolve the expression as a type, a null
+               // value will be returned if the expression is not a type
+               // reference
+               //
+               public virtual TypeExpr ResolveAsTypeTerminal (EmitContext ec)
+               {
+                       int errors = Report.Errors;
+
+                       TypeExpr te = ResolveAsTypeStep (ec) as TypeExpr;
+
+                       if ((te == null) || (te.eclass != ExprClass.Type) || (te.Type == null)) {
+                               if (errors == Report.Errors)
+                                       Report.Error (246, Location, "Cannot find type '{0}'", ToString ());
+                               return null;
+                       }
+
+                       if (!te.CheckAccessLevel (ec.DeclSpace)) {
+                               Report.Error (122, Location, "'{0}' is inaccessible due to its protection level", te.Name);
+                               return null;
+                       }
+
+                       return te;
+               }
+              
+               /// <summary>
+               ///   Resolves an expression and performs semantic analysis on it.
+               /// </summary>
+               ///
+               /// <remarks>
+               ///   Currently Resolve wraps DoResolve to perform sanity
+               ///   checking and assertion checking on what we expect from Resolve.
+               /// </remarks>
+               public Expression Resolve (EmitContext ec, ResolveFlags flags)
+               {
+                       if ((flags & ResolveFlags.MaskExprClass) == ResolveFlags.Type) 
+                               return ResolveAsTypeStep (ec);
+
+                       bool old_do_flow_analysis = ec.DoFlowAnalysis;
+                       if ((flags & ResolveFlags.DisableFlowAnalysis) != 0)
+                               ec.DoFlowAnalysis = false;
+
+                       Expression e;
+                       bool intermediate = (flags & ResolveFlags.Intermediate) == ResolveFlags.Intermediate;
+                       if (this is SimpleName)
+                               e = ((SimpleName) this).DoResolveAllowStatic (ec, intermediate);
+
+                       else 
+                               e = DoResolve (ec);
+
+                       ec.DoFlowAnalysis = old_do_flow_analysis;
+
+                       if (e == null)
+                               return null;
+
+                       if (e is SimpleName){
+                               SimpleName s = (SimpleName) e;
+
+                               if ((flags & ResolveFlags.SimpleName) == 0) {
+                                       MemberLookupFailed (ec, null, ec.ContainerType, s.Name,
+                                                           ec.DeclSpace.Name, loc);
+                                       return null;
+                               }
+
+                               return s;
+                       }
+
+                       if ((e is TypeExpr) || (e is ComposedCast)) {
+                               if ((flags & ResolveFlags.Type) == 0) {
+                                       e.Error_UnexpectedKind (flags, loc);
+                                       return null;
+                               }
+
+                               return e;
+                       }
+
+                       switch (e.eclass) {
+                       case ExprClass.Type:
+                               if ((flags & ResolveFlags.VariableOrValue) == 0) {
+                                       e.Error_UnexpectedKind (flags, loc);
+                                       return null;
+                               }
+                               break;
+
+                       case ExprClass.MethodGroup:
+                               if (RootContext.Version == LanguageVersion.ISO_1){
+                                       if ((flags & ResolveFlags.MethodGroup) == 0) {
+                                               ((MethodGroupExpr) e).ReportUsageError ();
+                                               return null;
+                                       }
+                               }
+                               break;
+
+                       case ExprClass.Value:
+                       case ExprClass.Variable:
+                       case ExprClass.PropertyAccess:
+                       case ExprClass.EventAccess:
+                       case ExprClass.IndexerAccess:
+                               if ((flags & ResolveFlags.VariableOrValue) == 0) {
+                                       Console.WriteLine ("I got: {0} and {1}", e.GetType (), e);
+                                       Console.WriteLine ("I am {0} and {1}", this.GetType (), this);
+                                       FieldInfo fi = ((FieldExpr) e).FieldInfo;
+                                       
+                                       Console.WriteLine ("{0} and {1}", fi.DeclaringType, fi.Name);
+                                       e.Error_UnexpectedKind (flags, loc);
+                                       return null;
+                               }
+                               break;
+
+                       default:
+                               throw new Exception ("Expression " + e.GetType () +
+                                                    " ExprClass is Invalid after resolve");
+                       }
+
+                       if (e.type == null)
+                               throw new Exception (
+                                       "Expression " + e.GetType () +
+                                       " did not set its type after Resolve\n" +
+                                       "called from: " + this.GetType ());
+
+                       return e;
+               }
+
+               /// <summary>
+               ///   Resolves an expression and performs semantic analysis on it.
+               /// </summary>
+               public Expression Resolve (EmitContext ec)
+               {
+                       return Resolve (ec, ResolveFlags.VariableOrValue);
+               }
+
+               /// <summary>
+               ///   Resolves an expression for LValue assignment
+               /// </summary>
+               ///
+               /// <remarks>
+               ///   Currently ResolveLValue wraps DoResolveLValue to perform sanity
+               ///   checking and assertion checking on what we expect from Resolve
+               /// </remarks>
+               public Expression ResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       Expression e = DoResolveLValue (ec, right_side);
+
+                       if (e != null){
+                               if (e is SimpleName){
+                                       SimpleName s = (SimpleName) e;
+                                       MemberLookupFailed (ec, null, ec.ContainerType, s.Name,
+                                                           ec.DeclSpace.Name, loc);
+                                       return null;
+                               }
+
+                               if (e.eclass == ExprClass.Invalid)
+                                       throw new Exception ("Expression " + e +
+                                                            " ExprClass is Invalid after resolve");
+
+                               if (e.eclass == ExprClass.MethodGroup) {
+                                       ((MethodGroupExpr) e).ReportUsageError ();
+                                       return null;
+                               }
+
+                               if ((e.type == null) && !(e is ConstructedType))
+                                       throw new Exception ("Expression " + e +
+                                                            " did not set its type after Resolve");
+                       }
+
+                       return e;
+               }
+               
+               /// <summary>
+               ///   Emits the code for the expression
+               /// </summary>
+               ///
+               /// <remarks>
+               ///   The Emit method is invoked to generate the code
+               ///   for the expression.  
+               /// </remarks>
+               public abstract void Emit (EmitContext ec);
+
+               public virtual void EmitBranchable (EmitContext ec, Label target, bool onTrue)
+               {
+                       Emit (ec);
+                       ec.ig.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+               }
+
+               /// <summary>
+               ///   Protected constructor.  Only derivate types should
+               ///   be able to be created
+               /// </summary>
+
+               protected Expression ()
+               {
+                       eclass = ExprClass.Invalid;
+                       type = null;
+               }
+
+               /// <summary>
+               ///   Returns a literalized version of a literal FieldInfo
+               /// </summary>
+               ///
+               /// <remarks>
+               ///   The possible return values are:
+               ///      IntConstant, UIntConstant
+               ///      LongLiteral, ULongConstant
+               ///      FloatConstant, DoubleConstant
+               ///      StringConstant
+               ///
+               ///   The value returned is already resolved.
+               /// </remarks>
+               public static Constant Constantify (object v, Type t)
+               {
+                       if (t == TypeManager.int32_type)
+                               return new IntConstant ((int) v);
+                       else if (t == TypeManager.uint32_type)
+                               return new UIntConstant ((uint) v);
+                       else if (t == TypeManager.int64_type)
+                               return new LongConstant ((long) v);
+                       else if (t == TypeManager.uint64_type)
+                               return new ULongConstant ((ulong) v);
+                       else if (t == TypeManager.float_type)
+                               return new FloatConstant ((float) v);
+                       else if (t == TypeManager.double_type)
+                               return new DoubleConstant ((double) v);
+                       else if (t == TypeManager.string_type)
+                               return new StringConstant ((string) v);
+                       else if (t == TypeManager.short_type)
+                               return new ShortConstant ((short)v);
+                       else if (t == TypeManager.ushort_type)
+                               return new UShortConstant ((ushort)v);
+                       else if (t == TypeManager.sbyte_type)
+                               return new SByteConstant (((sbyte)v));
+                       else if (t == TypeManager.byte_type)
+                               return new ByteConstant ((byte)v);
+                       else if (t == TypeManager.char_type)
+                               return new CharConstant ((char)v);
+                       else if (t == TypeManager.bool_type)
+                               return new BoolConstant ((bool) v);
+                       else if (t == TypeManager.decimal_type)
+                               return new DecimalConstant ((decimal) v);
+                       else if (TypeManager.IsEnumType (t)){
+                               Type real_type = TypeManager.TypeToCoreType (v.GetType ());
+                               if (real_type == t)
+                                       real_type = System.Enum.GetUnderlyingType (real_type);
+
+                               Constant e = Constantify (v, real_type);
+
+                               return new EnumConstant (e, t);
+                       } else if (v == null && !TypeManager.IsValueType (t))
+                               return NullLiteral.Null;
+                       else
+                               throw new Exception ("Unknown type for constant (" + t +
+                                                    "), details: " + v);
+               }
+
+               /// <summary>
+               ///   Returns a fully formed expression after a MemberLookup
+               /// </summary>
+               public static Expression ExprClassFromMemberInfo (EmitContext ec, MemberInfo mi, Location loc)
+               {
+                       if (mi is EventInfo)
+                               return new EventExpr ((EventInfo) mi, loc);
+                       else if (mi is FieldInfo)
+                               return new FieldExpr ((FieldInfo) mi, loc);
+                       else if (mi is PropertyInfo)
+                               return new PropertyExpr (ec, (PropertyInfo) mi, loc);
+                       else if (mi is Type){
+                               return new TypeExpression ((System.Type) mi, loc);
+                       }
+
+                       return null;
+               }
+
+
+               private static ArrayList almostMatchedMembers = new ArrayList (4);
+
+               //
+               // FIXME: Probably implement a cache for (t,name,current_access_set)?
+               //
+               // This code could use some optimizations, but we need to do some
+               // measurements.  For example, we could use a delegate to `flag' when
+               // something can not any longer be a method-group (because it is something
+               // else).
+               //
+               // Return values:
+               //     If the return value is an Array, then it is an array of
+               //     MethodBases
+               //   
+               //     If the return value is an MemberInfo, it is anything, but a Method
+               //
+               //     null on error.
+               //
+               // FIXME: When calling MemberLookup inside an `Invocation', we should pass
+               // the arguments here and have MemberLookup return only the methods that
+               // match the argument count/type, unlike we are doing now (we delay this
+               // decision).
+               //
+               // This is so we can catch correctly attempts to invoke instance methods
+               // from a static body (scan for error 120 in ResolveSimpleName).
+               //
+               //
+               // FIXME: Potential optimization, have a static ArrayList
+               //
+
+               public static Expression MemberLookup (EmitContext ec, Type queried_type, string name,
+                                                      MemberTypes mt, BindingFlags bf, Location loc)
+               {
+                       return MemberLookup (ec, ec.ContainerType, null, queried_type, name, mt, bf, loc);
+               }
+
+               //
+               // Lookup type `queried_type' for code in class `container_type' with a qualifier of
+               // `qualifier_type' or null to lookup members in the current class.
+               //
+
+               public static Expression MemberLookup (EmitContext ec, Type container_type,
+                                                      Type qualifier_type, Type queried_type,
+                                                      string name, MemberTypes mt,
+                                                      BindingFlags bf, Location loc)
+               {
+                       almostMatchedMembers.Clear ();
+
+                       MemberInfo [] mi = TypeManager.MemberLookup (
+                               container_type, qualifier_type,queried_type, mt, bf, name,
+                               almostMatchedMembers);
+
+                       if (mi == null)
+                               return null;
+
+                       int count = mi.Length;
+
+                       if (mi [0] is MethodBase)
+                               return new MethodGroupExpr (mi, loc);
+
+                       if (count > 1)
+                               return null;
+
+                       return ExprClassFromMemberInfo (ec, mi [0], loc);
+               }
+
+               public const MemberTypes AllMemberTypes =
+                       MemberTypes.Constructor |
+                       MemberTypes.Event       |
+                       MemberTypes.Field       |
+                       MemberTypes.Method      |
+                       MemberTypes.NestedType  |
+                       MemberTypes.Property;
+               
+               public const BindingFlags AllBindingFlags =
+                       BindingFlags.Public |
+                       BindingFlags.Static |
+                       BindingFlags.Instance;
+
+               public static Expression MemberLookup (EmitContext ec, Type queried_type,
+                                                      string name, Location loc)
+               {
+                       return MemberLookup (ec, ec.ContainerType, null, queried_type, name,
+                                            AllMemberTypes, AllBindingFlags, loc);
+               }
+
+               public static Expression MemberLookup (EmitContext ec, Type qualifier_type,
+                                                      Type queried_type, string name, Location loc)
+               {
+                       return MemberLookup (ec, ec.ContainerType, qualifier_type, queried_type,
+                                            name, AllMemberTypes, AllBindingFlags, loc);
+               }
+
+               public static Expression MethodLookup (EmitContext ec, Type queried_type,
+                                                      string name, Location loc)
+               {
+                       return MemberLookup (ec, ec.ContainerType, null, queried_type, name,
+                                            MemberTypes.Method, AllBindingFlags, loc);
+               }
+
+               /// <summary>
+               ///   This is a wrapper for MemberLookup that is not used to "probe", but
+               ///   to find a final definition.  If the final definition is not found, we
+               ///   look for private members and display a useful debugging message if we
+               ///   find it.
+               /// </summary>
+               public static Expression MemberLookupFinal (EmitContext ec, Type qualifier_type,
+                                                           Type queried_type, string name,
+                                                           Location loc)
+               {
+                       return MemberLookupFinal (ec, qualifier_type, queried_type, name,
+                                                 AllMemberTypes, AllBindingFlags, loc);
+               }
+
+               public static Expression MemberLookupFinal (EmitContext ec, Type qualifier_type,
+                                                           Type queried_type, string name,
+                                                           MemberTypes mt, BindingFlags bf,
+                                                           Location loc)
+               {
+                       Expression e;
+
+                       int errors = Report.Errors;
+
+                       e = MemberLookup (ec, ec.ContainerType, qualifier_type, queried_type,
+                                         name, mt, bf, loc);
+
+                       if (e == null && errors == Report.Errors)
+                               // No errors were reported by MemberLookup, but there was an error.
+                               MemberLookupFailed (ec, qualifier_type, queried_type, name,
+                                                   null, loc);
+
+                       return e;
+               }
+
+               public static void MemberLookupFailed (EmitContext ec, Type qualifier_type,
+                                                      Type queried_type, string name,
+                                                      string class_name, Location loc)
+               {
+                       if (almostMatchedMembers.Count != 0) {
+                               if (qualifier_type == null) {
+                                       foreach (MemberInfo m in almostMatchedMembers)
+                                               Report.Error (38, loc, 
+                                                             "Cannot access non-static member `{0}' via nested type `{1}'", 
+                                                             TypeManager.GetFullNameSignature (m),
+                                                             TypeManager.CSharpName (ec.ContainerType));
+                                       return;
+                               }
+
+
+                               if (qualifier_type != ec.ContainerType) {
+                                       // Although a derived class can access protected members of
+                                       // its base class it cannot do so through an instance of the
+                                       // base class (CS1540).  If the qualifier_type is a parent of the
+                                       // ec.ContainerType and the lookup succeeds with the latter one,
+                                       // then we are in this situation.
+                                       foreach (MemberInfo m in almostMatchedMembers)
+                                               Report.Error (1540, loc, 
+                                                             "Cannot access protected member `{0}' via a qualifier of type `{1}';"
+                                                             + " the qualifier must be of type `{2}' (or derived from it)", 
+                                                             TypeManager.GetFullNameSignature (m),
+                                                             TypeManager.CSharpName (qualifier_type),
+                                                             TypeManager.CSharpName (ec.ContainerType));
+                                       return;
+                               }
+                               almostMatchedMembers.Clear ();
+                       }
+
+                       MemberInfo[] mi = TypeManager.MemberLookup (queried_type, null, queried_type,
+                                                                   AllMemberTypes, AllBindingFlags |
+                                                                   BindingFlags.NonPublic, name, null);
+
+                       if (mi == null) {
+                               if (class_name != null)
+                                       Report.Error (103, loc, "The name `" + name + "' could not be " +
+                                                     "found in `" + class_name + "'");
+                               else
+                                       Report.Error (
+                                               117, loc, "`" + queried_type + "' does not contain a " +
+                                               "definition for `" + name + "'");
+                               return;
+                       }
+
+                       if (TypeManager.MemberLookup (queried_type, null, queried_type,
+                                                     AllMemberTypes, AllBindingFlags |
+                                                     BindingFlags.NonPublic, name, null) == null) {
+                               if ((mi.Length == 1) && (mi [0] is Type)) {
+                                       Type t = (Type) mi [0];
+
+                                       Report.Error (305, loc,
+                                                     "Using the generic type `{0}' " +
+                                                     "requires {1} type arguments",
+                                                     TypeManager.GetFullName (t),
+                                                     TypeManager.GetNumberOfTypeArguments (t));
+                                       return;
+                               }
+                       }
+
+
+
+                       if (qualifier_type != null)
+                               Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", TypeManager.CSharpName (qualifier_type) + "." + name);
+                       else if (name == ".ctor") {
+                               Report.Error (143, loc, String.Format ("The type {0} has no constructors defined",
+                                                                      TypeManager.CSharpName (queried_type)));
+                       } else {
+                               Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", name);
+               }
+               }
+
+               static public MemberInfo GetFieldFromEvent (EventExpr event_expr)
+               {
+                       EventInfo ei = event_expr.EventInfo;
+
+                       return TypeManager.GetPrivateFieldOfEvent (ei);
+               }
+               
+               /// <summary>
+               ///   Returns an expression that can be used to invoke operator true
+               ///   on the expression if it exists.
+               /// </summary>
+               static public StaticCallExpr GetOperatorTrue (EmitContext ec, Expression e, Location loc)
+               {
+                       return GetOperatorTrueOrFalse (ec, e, true, loc);
+               }
+
+               /// <summary>
+               ///   Returns an expression that can be used to invoke operator false
+               ///   on the expression if it exists.
+               /// </summary>
+               static public StaticCallExpr GetOperatorFalse (EmitContext ec, Expression e, Location loc)
+               {
+                       return GetOperatorTrueOrFalse (ec, e, false, loc);
+               }
+
+               static StaticCallExpr GetOperatorTrueOrFalse (EmitContext ec, Expression e, bool is_true, Location loc)
+               {
+                       MethodBase method;
+                       Expression operator_group;
+
+                       operator_group = MethodLookup (ec, e.Type, is_true ? "op_True" : "op_False", loc);
+                       if (operator_group == null)
+                               return null;
+
+                       ArrayList arguments = new ArrayList ();
+                       arguments.Add (new Argument (e, Argument.AType.Expression));
+                       method = Invocation.OverloadResolve (
+                               ec, (MethodGroupExpr) operator_group, arguments, false, loc);
+
+                       if (method == null)
+                               return null;
+
+                       return new StaticCallExpr ((MethodInfo) method, arguments, loc);
+               }
+
+               /// <summary>
+               ///   Resolves the expression `e' into a boolean expression: either through
+               ///   an implicit conversion, or through an `operator true' invocation
+               /// </summary>
+               public static Expression ResolveBoolean (EmitContext ec, Expression e, Location loc)
+               {
+                       e = e.Resolve (ec);
+                       if (e == null)
+                               return null;
+
+                       if (e.Type == TypeManager.bool_type)
+                               return e;
+
+                       Expression converted = Convert.ImplicitConversion (ec, e, TypeManager.bool_type, new Location (-1));
+
+                       if (converted != null)
+                               return converted;
+
+                       //
+                       // If no implicit conversion to bool exists, try using `operator true'
+                       //
+                       Expression operator_true = Expression.GetOperatorTrue (ec, e, loc);
+                       if (operator_true == null){
+                               Report.Error (31, loc, "Can not convert the expression to a boolean");
+                               return null;
+                       }
+                       return operator_true;
+               }
+               
+               static string ExprClassName (ExprClass c)
+               {
+                       switch (c){
+                       case ExprClass.Invalid:
+                               return "Invalid";
+                       case ExprClass.Value:
+                               return "value";
+                       case ExprClass.Variable:
+                               return "variable";
+                       case ExprClass.Namespace:
+                               return "namespace";
+                       case ExprClass.Type:
+                               return "type";
+                       case ExprClass.MethodGroup:
+                               return "method group";
+                       case ExprClass.PropertyAccess:
+                               return "property access";
+                       case ExprClass.EventAccess:
+                               return "event access";
+                       case ExprClass.IndexerAccess:
+                               return "indexer access";
+                       case ExprClass.Nothing:
+                               return "null";
+                       }
+                       throw new Exception ("Should not happen");
+               }
+               
+               /// <summary>
+               ///   Reports that we were expecting `expr' to be of class `expected'
+               /// </summary>
+               public void Error_UnexpectedKind (string expected, Location loc)
+               {
+                       string kind = "Unknown";
+                       
+                       kind = ExprClassName (eclass);
+
+                       Report.Error (118, loc, "Expression denotes a `" + kind +
+                              "' where a `" + expected + "' was expected");
+               }
+
+               public void Error_UnexpectedKind (ResolveFlags flags, Location loc)
+               {
+                       ArrayList valid = new ArrayList (10);
+
+                       if ((flags & ResolveFlags.VariableOrValue) != 0) {
+                               valid.Add ("variable");
+                               valid.Add ("value");
+                       }
+
+                       if ((flags & ResolveFlags.Type) != 0)
+                               valid.Add ("type");
+
+                       if ((flags & ResolveFlags.MethodGroup) != 0)
+                               valid.Add ("method group");
+
+                       if ((flags & ResolveFlags.SimpleName) != 0)
+                               valid.Add ("simple name");
+
+                       if (valid.Count == 0)
+                               valid.Add ("unknown");
+
+                       StringBuilder sb = new StringBuilder ();
+                       for (int i = 0; i < valid.Count; i++) {
+                               if (i > 0)
+                                       sb.Append (", ");
+                               else if (i == valid.Count)
+                                       sb.Append (" or ");
+                               sb.Append (valid [i]);
+                       }
+
+                       string kind = ExprClassName (eclass);
+
+                       Error (119, "Expression denotes a `" + kind + "' where " +
+                              "a `" + sb.ToString () + "' was expected");
+               }
+               
+               static public void Error_ConstantValueCannotBeConverted (Location l, string val, Type t)
+               {
+                       Report.Error (31, l, "Constant value `" + val + "' cannot be converted to " +
+                                     TypeManager.CSharpName (t));
+               }
+
+               public static void UnsafeError (Location loc)
+               {
+                       Report.Error (214, loc, "Pointers may only be used in an unsafe context");
+               }
+               
+               /// <summary>
+               ///   Converts the IntConstant, UIntConstant, LongConstant or
+               ///   ULongConstant into the integral target_type.   Notice
+               ///   that we do not return an `Expression' we do return
+               ///   a boxed integral type.
+               ///
+               ///   FIXME: Since I added the new constants, we need to
+               ///   also support conversions from CharConstant, ByteConstant,
+               ///   SByteConstant, UShortConstant, ShortConstant
+               ///
+               ///   This is used by the switch statement, so the domain
+               ///   of work is restricted to the literals above, and the
+               ///   targets are int32, uint32, char, byte, sbyte, ushort,
+               ///   short, uint64 and int64
+               /// </summary>
+               public static object ConvertIntLiteral (Constant c, Type target_type, Location loc)
+               {
+                       if (!Convert.ImplicitStandardConversionExists (Convert.ConstantEC, c, target_type)){
+                               Convert.Error_CannotImplicitConversion (loc, c.Type, target_type);
+                               return null;
+                       }
+                       
+                       string s = "";
+
+                       if (c.Type == target_type)
+                               return ((Constant) c).GetValue ();
+
+                       //
+                       // Make into one of the literals we handle, we dont really care
+                       // about this value as we will just return a few limited types
+                       // 
+                       if (c is EnumConstant)
+                               c = ((EnumConstant)c).WidenToCompilerConstant ();
+
+                       if (c is IntConstant){
+                               int v = ((IntConstant) c).Value;
+                               
+                               if (target_type == TypeManager.uint32_type){
+                                       if (v >= 0)
+                                               return (uint) v;
+                               } else if (target_type == TypeManager.char_type){
+                                       if (v >= Char.MinValue && v <= Char.MaxValue)
+                                               return (char) v;
+                               } else if (target_type == TypeManager.byte_type){
+                                       if (v >= Byte.MinValue && v <= Byte.MaxValue)
+                                               return (byte) v;
+                               } else if (target_type == TypeManager.sbyte_type){
+                                       if (v >= SByte.MinValue && v <= SByte.MaxValue)
+                                               return (sbyte) v;
+                               } else if (target_type == TypeManager.short_type){
+                                       if (v >= Int16.MinValue && v <= UInt16.MaxValue)
+                                               return (short) v;
+                               } else if (target_type == TypeManager.ushort_type){
+                                       if (v >= UInt16.MinValue && v <= UInt16.MaxValue)
+                                               return (ushort) v;
+                               } else if (target_type == TypeManager.int64_type)
+                                       return (long) v;
+                               else if (target_type == TypeManager.uint64_type){
+                                       if (v > 0)
+                                               return (ulong) v;
+                               }
+
+                               s = v.ToString ();
+                       } else if (c is UIntConstant){
+                               uint v = ((UIntConstant) c).Value;
+
+                               if (target_type == TypeManager.int32_type){
+                                       if (v <= Int32.MaxValue)
+                                               return (int) v;
+                               } else if (target_type == TypeManager.char_type){
+                                       if (v >= Char.MinValue && v <= Char.MaxValue)
+                                               return (char) v;
+                               } else if (target_type == TypeManager.byte_type){
+                                       if (v <= Byte.MaxValue)
+                                               return (byte) v;
+                               } else if (target_type == TypeManager.sbyte_type){
+                                       if (v <= SByte.MaxValue)
+                                               return (sbyte) v;
+                               } else if (target_type == TypeManager.short_type){
+                                       if (v <= UInt16.MaxValue)
+                                               return (short) v;
+                               } else if (target_type == TypeManager.ushort_type){
+                                       if (v <= UInt16.MaxValue)
+                                               return (ushort) v;
+                               } else if (target_type == TypeManager.int64_type)
+                                       return (long) v;
+                               else if (target_type == TypeManager.uint64_type)
+                                       return (ulong) v;
+                               s = v.ToString ();
+                       } else if (c is LongConstant){ 
+                               long v = ((LongConstant) c).Value;
+
+                               if (target_type == TypeManager.int32_type){
+                                       if (v >= UInt32.MinValue && v <= UInt32.MaxValue)
+                                               return (int) v;
+                               } else if (target_type == TypeManager.uint32_type){
+                                       if (v >= 0 && v <= UInt32.MaxValue)
+                                               return (uint) v;
+                               } else if (target_type == TypeManager.char_type){
+                                       if (v >= Char.MinValue && v <= Char.MaxValue)
+                                               return (char) v;
+                               } else if (target_type == TypeManager.byte_type){
+                                       if (v >= Byte.MinValue && v <= Byte.MaxValue)
+                                               return (byte) v;
+                               } else if (target_type == TypeManager.sbyte_type){
+                                       if (v >= SByte.MinValue && v <= SByte.MaxValue)
+                                               return (sbyte) v;
+                               } else if (target_type == TypeManager.short_type){
+                                       if (v >= Int16.MinValue && v <= UInt16.MaxValue)
+                                               return (short) v;
+                               } else if (target_type == TypeManager.ushort_type){
+                                       if (v >= UInt16.MinValue && v <= UInt16.MaxValue)
+                                               return (ushort) v;
+                               } else if (target_type == TypeManager.uint64_type){
+                                       if (v > 0)
+                                               return (ulong) v;
+                               }
+                               s = v.ToString ();
+                       } else if (c is ULongConstant){
+                               ulong v = ((ULongConstant) c).Value;
+
+                               if (target_type == TypeManager.int32_type){
+                                       if (v <= Int32.MaxValue)
+                                               return (int) v;
+                               } else if (target_type == TypeManager.uint32_type){
+                                       if (v <= UInt32.MaxValue)
+                                               return (uint) v;
+                               } else if (target_type == TypeManager.char_type){
+                                       if (v >= Char.MinValue && v <= Char.MaxValue)
+                                               return (char) v;
+                               } else if (target_type == TypeManager.byte_type){
+                                       if (v >= Byte.MinValue && v <= Byte.MaxValue)
+                                               return (byte) v;
+                               } else if (target_type == TypeManager.sbyte_type){
+                                       if (v <= (int) SByte.MaxValue)
+                                               return (sbyte) v;
+                               } else if (target_type == TypeManager.short_type){
+                                       if (v <= UInt16.MaxValue)
+                                               return (short) v;
+                               } else if (target_type == TypeManager.ushort_type){
+                                       if (v <= UInt16.MaxValue)
+                                               return (ushort) v;
+                               } else if (target_type == TypeManager.int64_type){
+                                       if (v <= Int64.MaxValue)
+                                               return (long) v;
+                               }
+                               s = v.ToString ();
+                       } else if (c is ByteConstant){
+                               byte v = ((ByteConstant) c).Value;
+                               
+                               if (target_type == TypeManager.int32_type)
+                                       return (int) v;
+                               else if (target_type == TypeManager.uint32_type)
+                                       return (uint) v;
+                               else if (target_type == TypeManager.char_type)
+                                       return (char) v;
+                               else if (target_type == TypeManager.sbyte_type){
+                                       if (v <= SByte.MaxValue)
+                                               return (sbyte) v;
+                               } else if (target_type == TypeManager.short_type)
+                                       return (short) v;
+                               else if (target_type == TypeManager.ushort_type)
+                                       return (ushort) v;
+                               else if (target_type == TypeManager.int64_type)
+                                       return (long) v;
+                               else if (target_type == TypeManager.uint64_type)
+                                       return (ulong) v;
+                               s = v.ToString ();
+                       } else if (c is SByteConstant){
+                               sbyte v = ((SByteConstant) c).Value;
+                               
+                               if (target_type == TypeManager.int32_type)
+                                       return (int) v;
+                               else if (target_type == TypeManager.uint32_type){
+                                       if (v >= 0)
+                                               return (uint) v;
+                               } else if (target_type == TypeManager.char_type){
+                                       if (v >= 0)
+                                               return (char) v;
+                               } else if (target_type == TypeManager.byte_type){
+                                       if (v >= 0)
+                                               return (byte) v;
+                               } else if (target_type == TypeManager.short_type)
+                                       return (short) v;
+                               else if (target_type == TypeManager.ushort_type){
+                                       if (v >= 0)
+                                               return (ushort) v;
+                               } else if (target_type == TypeManager.int64_type)
+                                       return (long) v;
+                               else if (target_type == TypeManager.uint64_type){
+                                       if (v >= 0)
+                                               return (ulong) v;
+                               }
+                               s = v.ToString ();
+                       } else if (c is ShortConstant){
+                               short v = ((ShortConstant) c).Value;
+                               
+                               if (target_type == TypeManager.int32_type){
+                                       return (int) v;
+                               } else if (target_type == TypeManager.uint32_type){
+                                       if (v >= 0)
+                                               return (uint) v;
+                               } else if (target_type == TypeManager.char_type){
+                                       if (v >= 0)
+                                               return (char) v;
+                               } else if (target_type == TypeManager.byte_type){
+                                       if (v >= Byte.MinValue && v <= Byte.MaxValue)
+                                               return (byte) v;
+                               } else if (target_type == TypeManager.sbyte_type){
+                                       if (v >= SByte.MinValue && v <= SByte.MaxValue)
+                                               return (sbyte) v;
+                               } else if (target_type == TypeManager.ushort_type){
+                                       if (v >= 0)
+                                               return (ushort) v;
+                               } else if (target_type == TypeManager.int64_type)
+                                       return (long) v;
+                               else if (target_type == TypeManager.uint64_type)
+                                       return (ulong) v;
+
+                               s = v.ToString ();
+                       } else if (c is UShortConstant){
+                               ushort v = ((UShortConstant) c).Value;
+                               
+                               if (target_type == TypeManager.int32_type)
+                                       return (int) v;
+                               else if (target_type == TypeManager.uint32_type)
+                                       return (uint) v;
+                               else if (target_type == TypeManager.char_type){
+                                       if (v >= Char.MinValue && v <= Char.MaxValue)
+                                               return (char) v;
+                               } else if (target_type == TypeManager.byte_type){
+                                       if (v >= Byte.MinValue && v <= Byte.MaxValue)
+                                               return (byte) v;
+                               } else if (target_type == TypeManager.sbyte_type){
+                                       if (v <= SByte.MaxValue)
+                                               return (byte) v;
+                               } else if (target_type == TypeManager.short_type){
+                                       if (v <= Int16.MaxValue)
+                                               return (short) v;
+                               } else if (target_type == TypeManager.int64_type)
+                                       return (long) v;
+                               else if (target_type == TypeManager.uint64_type)
+                                       return (ulong) v;
+
+                               s = v.ToString ();
+                       } else if (c is CharConstant){
+                               char v = ((CharConstant) c).Value;
+                               
+                               if (target_type == TypeManager.int32_type)
+                                       return (int) v;
+                               else if (target_type == TypeManager.uint32_type)
+                                       return (uint) v;
+                               else if (target_type == TypeManager.byte_type){
+                                       if (v >= Byte.MinValue && v <= Byte.MaxValue)
+                                               return (byte) v;
+                               } else if (target_type == TypeManager.sbyte_type){
+                                       if (v <= SByte.MaxValue)
+                                               return (sbyte) v;
+                               } else if (target_type == TypeManager.short_type){
+                                       if (v <= Int16.MaxValue)
+                                               return (short) v;
+                               } else if (target_type == TypeManager.ushort_type)
+                                       return (short) v;
+                               else if (target_type == TypeManager.int64_type)
+                                       return (long) v;
+                               else if (target_type == TypeManager.uint64_type)
+                                       return (ulong) v;
+
+                               s = v.ToString ();
+                       }
+                       Error_ConstantValueCannotBeConverted (loc, s, target_type);
+                       return null;
+               }
+
+               //
+               // Load the object from the pointer.  
+               //
+               public static void LoadFromPtr (ILGenerator ig, Type t)
+               {
+                       if (t == TypeManager.int32_type)
+                               ig.Emit (OpCodes.Ldind_I4);
+                       else if (t == TypeManager.uint32_type)
+                               ig.Emit (OpCodes.Ldind_U4);
+                       else if (t == TypeManager.short_type)
+                               ig.Emit (OpCodes.Ldind_I2);
+                       else if (t == TypeManager.ushort_type)
+                               ig.Emit (OpCodes.Ldind_U2);
+                       else if (t == TypeManager.char_type)
+                               ig.Emit (OpCodes.Ldind_U2);
+                       else if (t == TypeManager.byte_type)
+                               ig.Emit (OpCodes.Ldind_U1);
+                       else if (t == TypeManager.sbyte_type)
+                               ig.Emit (OpCodes.Ldind_I1);
+                       else if (t == TypeManager.uint64_type)
+                               ig.Emit (OpCodes.Ldind_I8);
+                       else if (t == TypeManager.int64_type)
+                               ig.Emit (OpCodes.Ldind_I8);
+                       else if (t == TypeManager.float_type)
+                               ig.Emit (OpCodes.Ldind_R4);
+                       else if (t == TypeManager.double_type)
+                               ig.Emit (OpCodes.Ldind_R8);
+                       else if (t == TypeManager.bool_type)
+                               ig.Emit (OpCodes.Ldind_I1);
+                       else if (t == TypeManager.intptr_type)
+                               ig.Emit (OpCodes.Ldind_I);
+                       else if (TypeManager.IsEnumType (t)) {
+                               if (t == TypeManager.enum_type)
+                                       ig.Emit (OpCodes.Ldind_Ref);
+                               else
+                                       LoadFromPtr (ig, TypeManager.EnumToUnderlying (t));
+                       } else if (t.IsValueType || t.IsGenericParameter)
+                               ig.Emit (OpCodes.Ldobj, t);
+                       else if (t.IsPointer)
+                               ig.Emit (OpCodes.Ldind_I);
+                       else
+                               ig.Emit (OpCodes.Ldind_Ref);
+               }
+
+               //
+               // The stack contains the pointer and the value of type `type'
+               //
+               public static void StoreFromPtr (ILGenerator ig, Type type)
+               {
+                       if (TypeManager.IsEnumType (type))
+                               type = TypeManager.EnumToUnderlying (type);
+                       if (type == TypeManager.int32_type || type == TypeManager.uint32_type)
+                               ig.Emit (OpCodes.Stind_I4);
+                       else if (type == TypeManager.int64_type || type == TypeManager.uint64_type)
+                               ig.Emit (OpCodes.Stind_I8);
+                       else if (type == TypeManager.char_type || type == TypeManager.short_type ||
+                                type == TypeManager.ushort_type)
+                               ig.Emit (OpCodes.Stind_I2);
+                       else if (type == TypeManager.float_type)
+                               ig.Emit (OpCodes.Stind_R4);
+                       else if (type == TypeManager.double_type)
+                               ig.Emit (OpCodes.Stind_R8);
+                       else if (type == TypeManager.byte_type || type == TypeManager.sbyte_type ||
+                                type == TypeManager.bool_type)
+                               ig.Emit (OpCodes.Stind_I1);
+                       else if (type == TypeManager.intptr_type)
+                               ig.Emit (OpCodes.Stind_I);
+                       else if (type.IsValueType || type.IsGenericParameter)
+                               ig.Emit (OpCodes.Stobj, type);
+                       else
+                               ig.Emit (OpCodes.Stind_Ref);
+               }
+               
+               //
+               // Returns the size of type `t' if known, otherwise, 0
+               //
+               public static int GetTypeSize (Type t)
+               {
+                       t = TypeManager.TypeToCoreType (t);
+                       if (t == TypeManager.int32_type ||
+                           t == TypeManager.uint32_type ||
+                           t == TypeManager.float_type)
+                               return 4;
+                       else if (t == TypeManager.int64_type ||
+                                t == TypeManager.uint64_type ||
+                                t == TypeManager.double_type)
+                               return 8;
+                       else if (t == TypeManager.byte_type ||
+                                t == TypeManager.sbyte_type ||
+                                t == TypeManager.bool_type)    
+                               return 1;
+                       else if (t == TypeManager.short_type ||
+                                t == TypeManager.char_type ||
+                                t == TypeManager.ushort_type)
+                               return 2;
+                       else if (t == TypeManager.decimal_type)
+                               return 16;
+                       else
+                               return 0;
+               }
+
+               public static void Error_NegativeArrayIndex (Location loc)
+               {
+                       Report.Error (248, loc, "Cannot create an array with a negative size");
+               }
+               
+               //
+               // Converts `source' to an int, uint, long or ulong.
+               //
+               public Expression ExpressionToArrayArgument (EmitContext ec, Expression source, Location loc)
+               {
+                       Expression target;
+                       
+                       bool old_checked = ec.CheckState;
+                       ec.CheckState = true;
+                       
+                       target = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, loc);
+                       if (target == null){
+                               target = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, loc);
+                               if (target == null){
+                                       target = Convert.ImplicitConversion (ec, source, TypeManager.int64_type, loc);
+                                       if (target == null){
+                                               target = Convert.ImplicitConversion (ec, source, TypeManager.uint64_type, loc);
+                                               if (target == null)
+                                                       Convert.Error_CannotImplicitConversion (loc, source.Type, TypeManager.int32_type);
+                                       }
+                               }
+                       } 
+                       ec.CheckState = old_checked;
+
+                       //
+                       // Only positive constants are allowed at compile time
+                       //
+                       if (target is Constant){
+                               if (target is IntConstant){
+                                       if (((IntConstant) target).Value < 0){
+                                               Error_NegativeArrayIndex (loc);
+                                               return null;
+                                       }
+                               }
+
+                               if (target is LongConstant){
+                                       if (((LongConstant) target).Value < 0){
+                                               Error_NegativeArrayIndex (loc);
+                                               return null;
+                                       }
+                               }
+                               
+                       }
+
+                       return target;
+               }
+               
+       }
+
+       /// <summary>
+       ///   This is just a base class for expressions that can
+       ///   appear on statements (invocations, object creation,
+       ///   assignments, post/pre increment and decrement).  The idea
+       ///   being that they would support an extra Emition interface that
+       ///   does not leave a result on the stack.
+       /// </summary>
+       public abstract class ExpressionStatement : Expression {
+
+               public virtual ExpressionStatement ResolveStatement (EmitContext ec)
+               {
+                       Expression e = Resolve (ec);
+                       if (e == null)
+                               return null;
+
+                       ExpressionStatement es = e as ExpressionStatement;
+                       if (es == null)
+                               Error (201, "Only assignment, call, increment, decrement and new object " +
+                                      "expressions can be used as a statement");
+
+                       return es;
+               }
+
+               /// <summary>
+               ///   Requests the expression to be emitted in a `statement'
+               ///   context.  This means that no new value is left on the
+               ///   stack after invoking this method (constrasted with
+               ///   Emit that will always leave a value on the stack).
+               /// </summary>
+               public abstract void EmitStatement (EmitContext ec);
+       }
+
+       /// <summary>
+       ///   This kind of cast is used to encapsulate the child
+       ///   whose type is child.Type into an expression that is
+       ///   reported to return "return_type".  This is used to encapsulate
+       ///   expressions which have compatible types, but need to be dealt
+       ///   at higher levels with.
+       ///
+       ///   For example, a "byte" expression could be encapsulated in one
+       ///   of these as an "unsigned int".  The type for the expression
+       ///   would be "unsigned int".
+       ///
+       /// </summary>
+       public class EmptyCast : Expression {
+               protected Expression child;
+               
+               public Expression Child {
+                       get {
+                               return child;
+                       }
+               }               
+
+               public EmptyCast (Expression child, Type return_type)
+               {
+                       eclass = child.eclass;
+                       type = return_type;
+                       this.child = child;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       // This should never be invoked, we are born in fully
+                       // initialized state.
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       child.Emit (ec);
+               }
+       }
+
+        //
+       // We need to special case this since an empty cast of
+       // a NullLiteral is still a Constant
+       //
+       public class NullCast : Constant {
+               protected Expression child;
+                               
+               public NullCast (Expression child, Type return_type)
+               {
+                       eclass = child.eclass;
+                       type = return_type;
+                       this.child = child;
+               }
+
+               override public string AsString ()
+               {
+                       return "null";
+               }
+
+               public override object GetValue ()
+               {
+                       return null;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       // This should never be invoked, we are born in fully
+                       // initialized state.
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       child.Emit (ec);
+               }
+
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+       }
+
+
+       /// <summary>
+       ///  This class is used to wrap literals which belong inside Enums
+       /// </summary>
+       public class EnumConstant : Constant {
+               public Constant Child;
+
+               public EnumConstant (Constant child, Type enum_type)
+               {
+                       eclass = child.eclass;
+                       this.Child = child;
+                       type = enum_type;
+               }
+               
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       // This should never be invoked, we are born in fully
+                       // initialized state.
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       Child.Emit (ec);
+               }
+
+               public override object GetValue ()
+               {
+                       return Child.GetValue ();
+               }
+
+               public object GetValueAsEnumType ()
+               {
+                       return System.Enum.ToObject (type, Child.GetValue ());
+               }
+
+               //
+               // Converts from one of the valid underlying types for an enumeration
+               // (int32, uint32, int64, uint64, short, ushort, byte, sbyte) to
+               // one of the internal compiler literals: Int/UInt/Long/ULong Literals.
+               //
+               public Constant WidenToCompilerConstant ()
+               {
+                       Type t = TypeManager.EnumToUnderlying (Child.Type);
+                       object v = ((Constant) Child).GetValue ();;
+                       
+                       if (t == TypeManager.int32_type)
+                               return new IntConstant ((int) v);
+                       if (t == TypeManager.uint32_type)
+                               return new UIntConstant ((uint) v);
+                       if (t == TypeManager.int64_type)
+                               return new LongConstant ((long) v);
+                       if (t == TypeManager.uint64_type)
+                               return new ULongConstant ((ulong) v);
+                       if (t == TypeManager.short_type)
+                               return new ShortConstant ((short) v);
+                       if (t == TypeManager.ushort_type)
+                               return new UShortConstant ((ushort) v);
+                       if (t == TypeManager.byte_type)
+                               return new ByteConstant ((byte) v);
+                       if (t == TypeManager.sbyte_type)
+                               return new SByteConstant ((sbyte) v);
+
+                       throw new Exception ("Invalid enumeration underlying type: " + t);
+               }
+
+               //
+               // Extracts the value in the enumeration on its native representation
+               //
+               public object GetPlainValue ()
+               {
+                       Type t = TypeManager.EnumToUnderlying (Child.Type);
+                       object v = ((Constant) Child).GetValue ();;
+                       
+                       if (t == TypeManager.int32_type)
+                               return (int) v;
+                       if (t == TypeManager.uint32_type)
+                               return (uint) v;
+                       if (t == TypeManager.int64_type)
+                               return (long) v;
+                       if (t == TypeManager.uint64_type)
+                               return (ulong) v;
+                       if (t == TypeManager.short_type)
+                               return (short) v;
+                       if (t == TypeManager.ushort_type)
+                               return (ushort) v;
+                       if (t == TypeManager.byte_type)
+                               return (byte) v;
+                       if (t == TypeManager.sbyte_type)
+                               return (sbyte) v;
+
+                       return null;
+               }
+               
+               public override string AsString ()
+               {
+                       return Child.AsString ();
+               }
+
+               public override DoubleConstant ConvertToDouble ()
+               {
+                       return Child.ConvertToDouble ();
+               }
+
+               public override FloatConstant ConvertToFloat ()
+               {
+                       return Child.ConvertToFloat ();
+               }
+
+               public override ULongConstant ConvertToULong ()
+               {
+                       return Child.ConvertToULong ();
+               }
+
+               public override LongConstant ConvertToLong ()
+               {
+                       return Child.ConvertToLong ();
+               }
+
+               public override UIntConstant ConvertToUInt ()
+               {
+                       return Child.ConvertToUInt ();
+               }
+
+               public override IntConstant ConvertToInt ()
+               {
+                       return Child.ConvertToInt ();
+               }
+               
+               public override bool IsZeroInteger {
+                       get { return Child.IsZeroInteger; }
+               }
+
+               public override bool IsNegative {
+                       get {
+                               return Child.IsNegative;
+                       }
+               }
+       }
+
+       /// <summary>
+       ///   This kind of cast is used to encapsulate Value Types in objects.
+       ///
+       ///   The effect of it is to box the value type emitted by the previous
+       ///   operation.
+       /// </summary>
+       public class BoxedCast : EmptyCast {
+
+               public BoxedCast (Expression expr)
+                       : base (expr, TypeManager.object_type) 
+               {
+                       eclass = ExprClass.Value;
+               }
+
+               public BoxedCast (Expression expr, Type target_type)
+                       : base (expr, target_type)
+               {
+                       eclass = ExprClass.Value;
+               }
+               
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       // This should never be invoked, we are born in fully
+                       // initialized state.
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       base.Emit (ec);
+                       
+                       ec.ig.Emit (OpCodes.Box, child.Type);
+               }
+       }
+
+       public class UnboxCast : EmptyCast {
+               public UnboxCast (Expression expr, Type return_type)
+                       : base (expr, return_type)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       // This should never be invoked, we are born in fully
+                       // initialized state.
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       Type t = type;
+                       ILGenerator ig = ec.ig;
+                       
+                       base.Emit (ec);
+                       if (t.IsGenericParameter)
+                               ig.Emit (OpCodes.Unbox_Any, t);
+                       else {
+                               ig.Emit (OpCodes.Unbox, t);
+
+                               LoadFromPtr (ig, t);
+                       }
+               }
+       }
+       
+       /// <summary>
+       ///   This is used to perform explicit numeric conversions.
+       ///
+       ///   Explicit numeric conversions might trigger exceptions in a checked
+       ///   context, so they should generate the conv.ovf opcodes instead of
+       ///   conv opcodes.
+       /// </summary>
+       public class ConvCast : EmptyCast {
+               public enum Mode : byte {
+                       I1_U1, I1_U2, I1_U4, I1_U8, I1_CH,
+                       U1_I1, U1_CH,
+                       I2_I1, I2_U1, I2_U2, I2_U4, I2_U8, I2_CH,
+                       U2_I1, U2_U1, U2_I2, U2_CH,
+                       I4_I1, I4_U1, I4_I2, I4_U2, I4_U4, I4_U8, I4_CH,
+                       U4_I1, U4_U1, U4_I2, U4_U2, U4_I4, U4_CH,
+                       I8_I1, I8_U1, I8_I2, I8_U2, I8_I4, I8_U4, I8_U8, I8_CH,
+                       U8_I1, U8_U1, U8_I2, U8_U2, U8_I4, U8_U4, U8_I8, U8_CH,
+                       CH_I1, CH_U1, CH_I2,
+                       R4_I1, R4_U1, R4_I2, R4_U2, R4_I4, R4_U4, R4_I8, R4_U8, R4_CH,
+                       R8_I1, R8_U1, R8_I2, R8_U2, R8_I4, R8_U4, R8_I8, R8_U8, R8_CH, R8_R4
+               }
+
+               Mode mode;
+               bool checked_state;
+               
+               public ConvCast (EmitContext ec, Expression child, Type return_type, Mode m)
+                       : base (child, return_type)
+               {
+                       checked_state = ec.CheckState;
+                       mode = m;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       // This should never be invoked, we are born in fully
+                       // initialized state.
+
+                       return this;
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("ConvCast ({0}, {1})", mode, child);
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       base.Emit (ec);
+
+                       if (checked_state){
+                               switch (mode){
+                               case Mode.I1_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.I1_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I1_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.I1_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.I1_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+
+                               case Mode.U1_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+                               case Mode.U1_CH: /* nothing */ break;
+
+                               case Mode.I2_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
+                               case Mode.I2_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.I2_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I2_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.I2_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.I2_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+
+                               case Mode.U2_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+                               case Mode.U2_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+                               case Mode.U2_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+                               case Mode.U2_CH: /* nothing */ break;
+
+                               case Mode.I4_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
+                               case Mode.I4_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.I4_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
+                               case Mode.I4_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.I4_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I4_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.I4_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+
+                               case Mode.U4_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+                               case Mode.U4_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+                               case Mode.U4_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+                               case Mode.U4_U2: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+                               case Mode.U4_I4: ig.Emit (OpCodes.Conv_Ovf_I4_Un); break;
+                               case Mode.U4_CH: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+
+                               case Mode.I8_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
+                               case Mode.I8_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.I8_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
+                               case Mode.I8_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.I8_I4: ig.Emit (OpCodes.Conv_Ovf_I4); break;
+                               case Mode.I8_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.I8_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.I8_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+
+                               case Mode.U8_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+                               case Mode.U8_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+                               case Mode.U8_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+                               case Mode.U8_U2: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+                               case Mode.U8_I4: ig.Emit (OpCodes.Conv_Ovf_I4_Un); break;
+                               case Mode.U8_U4: ig.Emit (OpCodes.Conv_Ovf_U4_Un); break;
+                               case Mode.U8_I8: ig.Emit (OpCodes.Conv_Ovf_I8_Un); break;
+                               case Mode.U8_CH: ig.Emit (OpCodes.Conv_Ovf_U2_Un); break;
+
+                               case Mode.CH_I1: ig.Emit (OpCodes.Conv_Ovf_I1_Un); break;
+                               case Mode.CH_U1: ig.Emit (OpCodes.Conv_Ovf_U1_Un); break;
+                               case Mode.CH_I2: ig.Emit (OpCodes.Conv_Ovf_I2_Un); break;
+
+                               case Mode.R4_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
+                               case Mode.R4_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.R4_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
+                               case Mode.R4_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.R4_I4: ig.Emit (OpCodes.Conv_Ovf_I4); break;
+                               case Mode.R4_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.R4_I8: ig.Emit (OpCodes.Conv_Ovf_I8); break;
+                               case Mode.R4_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.R4_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+
+                               case Mode.R8_I1: ig.Emit (OpCodes.Conv_Ovf_I1); break;
+                               case Mode.R8_U1: ig.Emit (OpCodes.Conv_Ovf_U1); break;
+                               case Mode.R8_I2: ig.Emit (OpCodes.Conv_Ovf_I2); break;
+                               case Mode.R8_U2: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.R8_I4: ig.Emit (OpCodes.Conv_Ovf_I4); break;
+                               case Mode.R8_U4: ig.Emit (OpCodes.Conv_Ovf_U4); break;
+                               case Mode.R8_I8: ig.Emit (OpCodes.Conv_Ovf_I8); break;
+                               case Mode.R8_U8: ig.Emit (OpCodes.Conv_Ovf_U8); break;
+                               case Mode.R8_CH: ig.Emit (OpCodes.Conv_Ovf_U2); break;
+                               case Mode.R8_R4: ig.Emit (OpCodes.Conv_R4); break;
+                               }
+                       } else {
+                               switch (mode){
+                               case Mode.I1_U1: ig.Emit (OpCodes.Conv_U1); break;
+                               case Mode.I1_U2: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I1_U4: ig.Emit (OpCodes.Conv_U4); break;
+                               case Mode.I1_U8: ig.Emit (OpCodes.Conv_I8); break;
+                               case Mode.I1_CH: ig.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.U1_I1: ig.Emit (OpCodes.Conv_I1); break;
+                               case Mode.U1_CH: ig.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.I2_I1: ig.Emit (OpCodes.Conv_I1); break;
+                               case Mode.I2_U1: ig.Emit (OpCodes.Conv_U1); break;
+                               case Mode.I2_U2: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I2_U4: ig.Emit (OpCodes.Conv_U4); break;
+                               case Mode.I2_U8: ig.Emit (OpCodes.Conv_I8); break;
+                               case Mode.I2_CH: ig.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.U2_I1: ig.Emit (OpCodes.Conv_I1); break;
+                               case Mode.U2_U1: ig.Emit (OpCodes.Conv_U1); break;
+                               case Mode.U2_I2: ig.Emit (OpCodes.Conv_I2); break;
+                               case Mode.U2_CH: /* nothing */ break;
+
+                               case Mode.I4_I1: ig.Emit (OpCodes.Conv_I1); break;
+                               case Mode.I4_U1: ig.Emit (OpCodes.Conv_U1); break;
+                               case Mode.I4_I2: ig.Emit (OpCodes.Conv_I2); break;
+                               case Mode.I4_U4: /* nothing */ break;
+                               case Mode.I4_U2: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I4_U8: ig.Emit (OpCodes.Conv_I8); break;
+                               case Mode.I4_CH: ig.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.U4_I1: ig.Emit (OpCodes.Conv_I1); break;
+                               case Mode.U4_U1: ig.Emit (OpCodes.Conv_U1); break;
+                               case Mode.U4_I2: ig.Emit (OpCodes.Conv_I2); break;
+                               case Mode.U4_U2: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.U4_I4: /* nothing */ break;
+                               case Mode.U4_CH: ig.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.I8_I1: ig.Emit (OpCodes.Conv_I1); break;
+                               case Mode.I8_U1: ig.Emit (OpCodes.Conv_U1); break;
+                               case Mode.I8_I2: ig.Emit (OpCodes.Conv_I2); break;
+                               case Mode.I8_U2: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.I8_I4: ig.Emit (OpCodes.Conv_I4); break;
+                               case Mode.I8_U4: ig.Emit (OpCodes.Conv_U4); break;
+                               case Mode.I8_U8: /* nothing */ break;
+                               case Mode.I8_CH: ig.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.U8_I1: ig.Emit (OpCodes.Conv_I1); break;
+                               case Mode.U8_U1: ig.Emit (OpCodes.Conv_U1); break;
+                               case Mode.U8_I2: ig.Emit (OpCodes.Conv_I2); break;
+                               case Mode.U8_U2: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.U8_I4: ig.Emit (OpCodes.Conv_I4); break;
+                               case Mode.U8_U4: ig.Emit (OpCodes.Conv_U4); break;
+                               case Mode.U8_I8: /* nothing */ break;
+                               case Mode.U8_CH: ig.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.CH_I1: ig.Emit (OpCodes.Conv_I1); break;
+                               case Mode.CH_U1: ig.Emit (OpCodes.Conv_U1); break;
+                               case Mode.CH_I2: ig.Emit (OpCodes.Conv_I2); break;
+
+                               case Mode.R4_I1: ig.Emit (OpCodes.Conv_I1); break;
+                               case Mode.R4_U1: ig.Emit (OpCodes.Conv_U1); break;
+                               case Mode.R4_I2: ig.Emit (OpCodes.Conv_I2); break;
+                               case Mode.R4_U2: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.R4_I4: ig.Emit (OpCodes.Conv_I4); break;
+                               case Mode.R4_U4: ig.Emit (OpCodes.Conv_U4); break;
+                               case Mode.R4_I8: ig.Emit (OpCodes.Conv_I8); break;
+                               case Mode.R4_U8: ig.Emit (OpCodes.Conv_U8); break;
+                               case Mode.R4_CH: ig.Emit (OpCodes.Conv_U2); break;
+
+                               case Mode.R8_I1: ig.Emit (OpCodes.Conv_I1); break;
+                               case Mode.R8_U1: ig.Emit (OpCodes.Conv_U1); break;
+                               case Mode.R8_I2: ig.Emit (OpCodes.Conv_I2); break;
+                               case Mode.R8_U2: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.R8_I4: ig.Emit (OpCodes.Conv_I4); break;
+                               case Mode.R8_U4: ig.Emit (OpCodes.Conv_U4); break;
+                               case Mode.R8_I8: ig.Emit (OpCodes.Conv_I8); break;
+                               case Mode.R8_U8: ig.Emit (OpCodes.Conv_U8); break;
+                               case Mode.R8_CH: ig.Emit (OpCodes.Conv_U2); break;
+                               case Mode.R8_R4: ig.Emit (OpCodes.Conv_R4); break;
+                               }
+                       }
+               }
+       }
+       
+       public class OpcodeCast : EmptyCast {
+               OpCode op, op2;
+               bool second_valid;
+               
+               public OpcodeCast (Expression child, Type return_type, OpCode op)
+                       : base (child, return_type)
+                       
+               {
+                       this.op = op;
+                       second_valid = false;
+               }
+
+               public OpcodeCast (Expression child, Type return_type, OpCode op, OpCode op2)
+                       : base (child, return_type)
+                       
+               {
+                       this.op = op;
+                       this.op2 = op2;
+                       second_valid = true;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       // This should never be invoked, we are born in fully
+                       // initialized state.
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       base.Emit (ec);
+                       ec.ig.Emit (op);
+
+                       if (second_valid)
+                               ec.ig.Emit (op2);
+               }                       
+       }
+
+       /// <summary>
+       ///   This kind of cast is used to encapsulate a child and cast it
+       ///   to the class requested
+       /// </summary>
+       public class ClassCast : EmptyCast {
+               public ClassCast (Expression child, Type return_type)
+                       : base (child, return_type)
+                       
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       // This should never be invoked, we are born in fully
+                       // initialized state.
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       base.Emit (ec);
+
+                       if (child.Type.IsGenericParameter)
+                               ec.ig.Emit (OpCodes.Box, child.Type);
+
+                       if (type.IsGenericParameter)
+                               ec.ig.Emit (OpCodes.Unbox_Any, type);
+                       else
+                               ec.ig.Emit (OpCodes.Castclass, type);
+               }
+       }
+       
+       /// <summary>
+       ///   SimpleName expressions are initially formed of a single
+       ///   word and it only happens at the beginning of the expression.
+       /// </summary>
+       ///
+       /// <remarks>
+       ///   The expression will try to be bound to a Field, a Method
+       ///   group or a Property.  If those fail we pass the name to our
+       ///   caller and the SimpleName is compounded to perform a type
+       ///   lookup.  The idea behind this process is that we want to avoid
+       ///   creating a namespace map from the assemblies, as that requires
+       ///   the GetExportedTypes function to be called and a hashtable to
+       ///   be constructed which reduces startup time.  If later we find
+       ///   that this is slower, we should create a `NamespaceExpr' expression
+       ///   that fully participates in the resolution process. 
+       ///   
+       ///   For example `System.Console.WriteLine' is decomposed into
+       ///   MemberAccess (MemberAccess (SimpleName ("System"), "Console"), "WriteLine")
+       ///   
+       ///   The first SimpleName wont produce a match on its own, so it will
+       ///   be turned into:
+       ///   MemberAccess (SimpleName ("System.Console"), "WriteLine").
+       ///   
+       ///   System.Console will produce a TypeExpr match.
+       ///   
+       ///   The downside of this is that we might be hitting `LookupType' too many
+       ///   times with this scheme.
+       /// </remarks>
+       public class SimpleName : Expression {
+               public string Name;
+               public readonly TypeArguments Arguments;
+
+               //
+               // If true, then we are a simple name, not composed with a ".
+               //
+               bool is_base;
+
+               public SimpleName (string a, string b, Location l)
+               {
+                       Name = String.Concat (a, ".", b);
+                       loc = l;
+                       is_base = false;
+               }
+               
+               public SimpleName (string name, Location l)
+               {
+                       Name = name;
+                       loc = l;
+                       is_base = true;
+               }
+
+               public SimpleName (string name, TypeArguments args, Location l)
+               {
+                       Name = name;
+                       Arguments = args;
+                       loc = l;
+                       is_base = true;
+               }
+
+               public static void Error_ObjectRefRequired (EmitContext ec, Location l, string name)
+               {
+                       if (ec.IsFieldInitializer)
+                               Report.Error (
+                                       236, l,
+                                       "A field initializer cannot reference the non-static field, " +
+                                       "method or property `"+name+"'");
+                       else
+                               Report.Error (
+                                       120, l,
+                                       "An object reference is required " +
+                                       "for the non-static field `"+name+"'");
+               }
+               
+               //
+               // Checks whether we are trying to access an instance
+               // property, method or field from a static body.
+               //
+               Expression MemberStaticCheck (EmitContext ec, Expression e)
+               {
+                       if (e is IMemberExpr){
+                               IMemberExpr member = (IMemberExpr) e;
+                               
+                               if (!member.IsStatic){
+                                       Error_ObjectRefRequired (ec, loc, Name);
+                                       return null;
+                               }
+                       }
+
+                       return e;
+               }
+               
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       return SimpleNameResolve (ec, null, false, false);
+               }
+
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       return SimpleNameResolve (ec, right_side, false, false);
+               }
+               
+
+               public Expression DoResolveAllowStatic (EmitContext ec, bool intermediate)
+               {
+                       return SimpleNameResolve (ec, null, true, intermediate);
+               }
+
+               public override Expression ResolveAsTypeStep (EmitContext ec)
+               {
+                       DeclSpace ds = ec.DeclSpace;
+                       NamespaceEntry ns = ds.NamespaceEntry;
+                       Type t;
+                       IAlias alias_value;
+
+                       //
+                       // Since we are cheating: we only do the Alias lookup for
+                       // namespaces if the name does not include any dots in it
+                       //
+                       if (ns != null && is_base)
+                               alias_value = ns.LookupAlias (Name);
+                       else
+                               alias_value = null;
+
+                       TypeParameterExpr generic_type = ds.LookupGeneric (Name, loc);
+                       if (generic_type != null)
+                               return generic_type.ResolveAsTypeTerminal (ec);
+
+                       if (ec.ResolvingTypeTree){
+                               int errors = Report.Errors;
+                               Type dt = ds.FindType (loc, Name);
+                               
+                               if (Report.Errors != errors)
+                                       return null;
+                               
+                               if (dt != null)
+                                       return new TypeExpression (dt, loc);
+
+                               if (alias_value != null){
+                                       if (alias_value.IsType)
+                                               return alias_value.ResolveAsType (ec);
+                                       if ((t = RootContext.LookupType (ds, alias_value.Name, true, loc)) != null)
+                                               return new TypeExpression (t, loc);
+                               }
+                       }
+
+                       if ((t = RootContext.LookupType (ds, Name, true, loc)) != null)
+                               return new TypeExpression (t, loc);
+
+                       if (alias_value != null) {
+                               if (alias_value.IsType)
+                                       return alias_value.ResolveAsType (ec);
+                               if ((t = RootContext.LookupType (ds, alias_value.Name, true, loc)) != null)
+                                       return new TypeExpression (t, loc);
+                               
+                               // we have alias value, but it isn't Type, so try if it's namespace
+                               return new SimpleName (alias_value.Name, loc);
+                       }
+
+                       // No match, maybe our parent can compose us
+                       // into something meaningful.
+                       return this;
+               }
+
+               Expression SimpleNameResolve (EmitContext ec, Expression right_side,
+                                             bool allow_static, bool intermediate)
+               {
+                       Expression e = DoSimpleNameResolve (ec, right_side, allow_static, intermediate);
+                       if (e == null)
+                               return null;
+
+                       Block current_block = ec.CurrentBlock;
+                       if (current_block != null){
+                               //LocalInfo vi = current_block.GetLocalInfo (Name);
+                               if (is_base &&
+                                   current_block.IsVariableNameUsedInChildBlock(Name)) {
+                                       Report.Error (135, Location,
+                                                     "'{0}' has a different meaning in a " +
+                                                     "child block", Name);
+                                       return null;
+                               }
+                       }
+
+                       if (e.Type != null && e.Type.IsPointer && !ec.InUnsafe) {
+                               UnsafeError (loc);
+                               return null;
+                       }
+
+                       return e;
+               }
+
+               /// <remarks>
+               ///   7.5.2: Simple Names. 
+               ///
+               ///   Local Variables and Parameters are handled at
+               ///   parse time, so they never occur as SimpleNames.
+               ///
+               ///   The `allow_static' flag is used by MemberAccess only
+               ///   and it is used to inform us that it is ok for us to 
+               ///   avoid the static check, because MemberAccess might end
+               ///   up resolving the Name as a Type name and the access as
+               ///   a static type access.
+               ///
+               ///   ie: Type Type; .... { Type.GetType (""); }
+               ///
+               ///   Type is both an instance variable and a Type;  Type.GetType
+               ///   is the static method not an instance method of type.
+               /// </remarks>
+               Expression DoSimpleNameResolve (EmitContext ec, Expression right_side, bool allow_static, bool intermediate)
+               {
+                       Expression e = null;
+
+                       //
+                       // Stage 1: Performed by the parser (binding to locals or parameters).
+                       //
+                       Block current_block = ec.CurrentBlock;
+                       if (current_block != null){
+                               LocalInfo vi = current_block.GetLocalInfo (Name);
+                               if (vi != null){
+                                       Expression var;
+                                       
+                                       var = new LocalVariableReference (ec.CurrentBlock, Name, loc);
+                                       
+                                       if (right_side != null)
+                                               return var.ResolveLValue (ec, right_side);
+                                       else
+                                               return var.Resolve (ec);
+                               }
+
+                               ParameterReference pref = current_block.GetParameterReference (Name, loc);
+                               if (pref != null) {
+                                       if (right_side != null)
+                                               return pref.ResolveLValue (ec, right_side);
+                                       else
+                                               return pref.Resolve (ec);
+                               }
+                       }
+                       
+                       //
+                       // Stage 2: Lookup members 
+                       //
+
+                       DeclSpace lookup_ds = ec.DeclSpace;
+                       do {
+                               if (lookup_ds.TypeBuilder == null)
+                                       break;
+
+                               e = MemberLookup (ec, lookup_ds.TypeBuilder, Name, loc);
+                               if (e != null)
+                                       break;
+
+                               lookup_ds =lookup_ds.Parent;
+                       } while (lookup_ds != null);
+
+                       if (e == null && ec.ContainerType != null)
+                               e = MemberLookup (ec, ec.ContainerType, Name, loc);
+
+                       if (e == null) {
+                               //
+                               // Since we are cheating (is_base is our hint
+                               // that we are the beginning of the name): we
+                               // only do the Alias lookup for namespaces if
+                               // the name does not include any dots in it
+                               //
+                               NamespaceEntry ns = ec.DeclSpace.NamespaceEntry;
+                               if (is_base && ns != null){
+                                       IAlias alias_value = ns.LookupAlias (Name);
+                                       if (alias_value != null){
+                                               if (alias_value.IsType)
+                                                       return alias_value.ResolveAsType (ec);
+
+                                               Name = alias_value.Name;
+                                               Type t;
+
+                                               if ((t = TypeManager.LookupType (Name)) != null)
+                                                       return new TypeExpression (t, loc);
+                                       
+                                               // No match, maybe our parent can compose us
+                                               // into something meaningful.
+                                               return this;
+                                       }
+                               }
+
+                               return ResolveAsTypeStep (ec);
+                       }
+
+                       if (e is TypeExpr)
+                               return e;
+
+                       if (e is IMemberExpr) {
+                               e = MemberAccess.ResolveMemberAccess (ec, e, null, loc, this);
+                               if (e == null)
+                                       return null;
+
+                               IMemberExpr me = e as IMemberExpr;
+                               if (me == null)
+                                       return e;
+
+                               if (Arguments != null) {
+                                       MethodGroupExpr mg = me as MethodGroupExpr;
+                                       if (mg == null)
+                                               return null;
+
+                                       return mg.ResolveGeneric (ec, Arguments);
+                               }
+
+                               // This fails if ResolveMemberAccess() was unable to decide whether
+                               // it's a field or a type of the same name.
+                               
+                               if (!me.IsStatic && (me.InstanceExpression == null))
+                                       return e;
+
+                               if (!me.IsStatic &&
+                                   TypeManager.IsNestedFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
+                                   me.InstanceExpression.Type != me.DeclaringType &&
+                                   !TypeManager.IsFamilyAccessible (me.InstanceExpression.Type, me.DeclaringType) &&
+                                   (!intermediate || !MemberAccess.IdenticalNameAndTypeName (ec, this, e, loc))) {
+                                       Error (38, "Cannot access nonstatic member `" + me.Name + "' of " +
+                                              "outer type `" + me.DeclaringType + "' via nested type `" +
+                                              me.InstanceExpression.Type + "'");
+                                       return null;
+                               }
+
+                               return (right_side != null)
+                                       ? e.DoResolveLValue (ec, right_side)
+                                       : e.DoResolve (ec);
+                       }
+
+                       if (ec.IsStatic || ec.IsFieldInitializer){
+                               if (allow_static)
+                                       return e;
+
+                               return MemberStaticCheck (ec, e);
+                       } else
+                               return e;
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       //
+                       // If this is ever reached, then we failed to
+                       // find the name as a namespace
+                       //
+
+                       Error (103, "The name `" + Name +
+                              "' does not exist in the class `" +
+                              ec.DeclSpace.Name + "'");
+               }
+
+               public override string ToString ()
+               {
+                       return Name;
+               }
+       }
+       
+       /// <summary>
+       ///   Fully resolved expression that evaluates to a type
+       /// </summary>
+       public abstract class TypeExpr : Expression, IAlias {
+               override public Expression ResolveAsTypeStep (EmitContext ec)
+               {
+                       TypeExpr t = DoResolveAsTypeStep (ec);
+                       if (t == null)
+                               return null;
+
+                       eclass = ExprClass.Type;
+                       return t;
+               }
+
+               override public Expression DoResolve (EmitContext ec)
+               {
+                       return ResolveAsTypeTerminal (ec);
+               }
+
+               override public void Emit (EmitContext ec)
+               {
+                       throw new Exception ("Should never be called");
+               }
+
+               public virtual bool CheckAccessLevel (DeclSpace ds)
+               {
+                       return ds.CheckAccessLevel (Type);
+               }
+
+               public virtual bool AsAccessible (DeclSpace ds, int flags)
+               {
+                       return ds.AsAccessible (Type, flags);
+               }
+
+               public virtual bool IsClass {
+                       get { return Type.IsClass; }
+               }
+
+               public virtual bool IsValueType {
+                       get { return Type.IsValueType; }
+               }
+
+               public virtual bool IsInterface {
+                       get { return Type.IsInterface; }
+               }
+
+               public virtual bool IsSealed {
+                       get { return Type.IsSealed; }
+               }
+
+               public virtual bool CanInheritFrom ()
+               {
+                       if (Type == TypeManager.enum_type ||
+                           (Type == TypeManager.value_type && RootContext.StdLib) ||
+                           Type == TypeManager.multicast_delegate_type ||
+                           Type == TypeManager.delegate_type ||
+                           Type == TypeManager.array_type)
+                               return false;
+
+                       return true;
+               }
+
+               public virtual bool IsAttribute {
+                       get {
+                               return Type == TypeManager.attribute_type ||
+                                       Type.IsSubclassOf (TypeManager.attribute_type);
+                       }
+               }
+
+               protected abstract TypeExpr DoResolveAsTypeStep (EmitContext ec);
+
+               public abstract string Name {
+                       get;
+               }
+
+               public override bool Equals (object obj)
+               {
+                       TypeExpr tobj = obj as TypeExpr;
+                       if (tobj == null)
+                               return false;
+
+                       return Type == tobj.Type;
+               }
+
+               public override int GetHashCode ()
+               {
+                       return Type.GetHashCode ();
+               }
+               
+               public override string ToString ()
+               {
+                       return Name;
+               }
+
+               bool IAlias.IsType {
+                       get { return true; }
+               }
+
+               TypeExpr IAlias.ResolveAsType (EmitContext ec)
+               {
+                       return ResolveAsTypeTerminal (ec);
+               }
+       }
+
+       public class TypeExpression : TypeExpr, IAlias {
+               public TypeExpression (Type t, Location l)
+               {
+                       Type = t;
+                       eclass = ExprClass.Type;
+                       loc = l;
+               }
+
+               protected override TypeExpr DoResolveAsTypeStep (EmitContext ec)
+               {
+                       return this;
+               }
+
+               public override string Name {
+                       get {
+                               return Type.ToString ();
+                       }
+               }
+
+               string IAlias.Name {
+                       get {
+                               return Type.FullName != null ? Type.FullName : Type.Name;
+                       }
+               }
+       }
+
+       /// <summary>
+       ///   Used to create types from a fully qualified name.  These are just used
+       ///   by the parser to setup the core types.  A TypeLookupExpression is always
+       ///   classified as a type.
+       /// </summary>
+       public class TypeLookupExpression : TypeExpr {
+               string name;
+               
+               public TypeLookupExpression (string name)
+               {
+                       this.name = name;
+               }
+
+               protected override TypeExpr DoResolveAsTypeStep (EmitContext ec)
+               {
+                       if (type == null) {
+                               type = RootContext.LookupType (
+                                       ec.DeclSpace, name, false, Location.Null);
+                               if (type == null)
+                                       return null;
+                       }
+
+                       return this;
+               }
+
+               public override string Name {
+                       get {
+                               return name;
+                       }
+               }
+       }
+
+       /// <summary>
+       ///   Represents an "unbound generic type", ie. typeof (Foo<>).
+       ///   See 14.5.11.
+       /// </summary>
+       public class UnboundTypeExpression : TypeLookupExpression {
+               public UnboundTypeExpression (string name)
+                       : base (name)
+               { }
+       }
+
+       public class TypeAliasExpression : TypeExpr, IAlias {
+               IAlias alias;
+               TypeExpr texpr;
+               TypeArguments args;
+               string name;
+
+               public TypeAliasExpression (IAlias alias, TypeArguments args, Location l)
+               {
+                       this.alias = alias;
+                       this.args = args;
+                       loc = l;
+
+                       eclass = ExprClass.Type;
+                       if (args != null)
+                               name = alias.Name + "<" + args.ToString () + ">";
+                       else
+                               name = alias.Name;
+               }
+
+               public override string Name {
+                       get { return name; }
+               }
+
+               protected override TypeExpr DoResolveAsTypeStep (EmitContext ec)
+               {
+                       texpr = alias.ResolveAsType (ec);
+                       if (texpr == null)
+                               return null;
+
+                       Type type = texpr.Type;
+                       int num_args = TypeManager.GetNumberOfTypeArguments (type);
+
+                       if (args != null) {
+                               if (num_args == 0) {
+                                       Report.Error (308, loc,
+                                                     "The non-generic type `{0}' cannot " +
+                                                     "be used with type arguments.",
+                                                     TypeManager.CSharpName (type));
+                                       return null;
+                               }
+
+                               ConstructedType ctype = new ConstructedType (type, args, loc);
+                               return ctype.ResolveAsTypeTerminal (ec);
+                       } else if (num_args > 0) {
+                               Report.Error (305, loc,
+                                             "Using the generic type `{0}' " +
+                                             "requires {1} type arguments",
+                                             TypeManager.GetFullName (type), num_args);
+                               return null;
+                       }
+
+                       return new TypeExpression (type, loc);
+               }
+
+               public override bool CheckAccessLevel (DeclSpace ds)
+               {
+                       return texpr.CheckAccessLevel (ds);
+               }
+
+               public override bool AsAccessible (DeclSpace ds, int flags)
+               {
+                       return texpr.AsAccessible (ds, flags);
+               }
+
+               public override bool IsClass {
+                       get { return texpr.IsClass; }
+               }
+
+               public override bool IsValueType {
+                       get { return texpr.IsValueType; }
+               }
+
+               public override bool IsInterface {
+                       get { return texpr.IsInterface; }
+               }
+
+               public override bool IsSealed {
+                       get { return texpr.IsSealed; }
+               }
+
+               public override bool IsAttribute {
+                       get { return texpr.IsAttribute; }
+               }
+       }
+
+       /// <summary>
+       ///   MethodGroup Expression.
+       ///  
+       ///   This is a fully resolved expression that evaluates to a type
+       /// </summary>
+       public class MethodGroupExpr : Expression, IMemberExpr {
+               public MethodBase [] Methods;
+               Expression instance_expression = null;
+               bool is_explicit_impl = false;
+               bool has_type_arguments = false;
+               bool identical_type_name = false;
+               bool is_base;
+               
+               public MethodGroupExpr (MemberInfo [] mi, Location l)
+               {
+                       Methods = new MethodBase [mi.Length];
+                       mi.CopyTo (Methods, 0);
+                       eclass = ExprClass.MethodGroup;
+                       type = TypeManager.object_type;
+                       loc = l;
+               }
+
+               public MethodGroupExpr (ArrayList list, Location l)
+               {
+                       Methods = new MethodBase [list.Count];
+
+                       try {
+                               list.CopyTo (Methods, 0);
+                       } catch {
+                               foreach (MemberInfo m in list){
+                                       if (!(m is MethodBase)){
+                                               Console.WriteLine ("Name " + m.Name);
+                                               Console.WriteLine ("Found a: " + m.GetType ().FullName);
+                                       }
+                               }
+                               throw;
+                       }
+
+                       loc = l;
+                       eclass = ExprClass.MethodGroup;
+                       type = TypeManager.object_type;
+               }
+
+               public Type DeclaringType {
+                       get {
+                                //
+                                // We assume that the top-level type is in the end
+                                //
+                               return Methods [Methods.Length - 1].DeclaringType;
+                                //return Methods [0].DeclaringType;
+                       }
+               }
+               
+               //
+               // `A method group may have associated an instance expression' 
+               // 
+               public Expression InstanceExpression {
+                       get {
+                               return instance_expression;
+                       }
+
+                       set {
+                               instance_expression = value;
+                       }
+               }
+
+               public bool IsExplicitImpl {
+                       get {
+                               return is_explicit_impl;
+                       }
+
+                       set {
+                               is_explicit_impl = value;
+                       }
+               }
+
+               public bool HasTypeArguments {
+                       get {
+                               return has_type_arguments;
+                       }
+
+                       set {
+                               has_type_arguments = value;
+                       }
+               }
+
+               public bool IdenticalTypeName {
+                       get {
+                               return identical_type_name;
+                       }
+
+                       set {
+                               identical_type_name = value;
+                       }
+               }
+
+               public bool IsBase {
+                       get {
+                               return is_base;
+                       }
+                       set {
+                               is_base = value;
+                       }
+               }
+
+               public string Name {
+                       get {
+                               //return Methods [0].Name;
+                                return Methods [Methods.Length - 1].Name;
+                       }
+               }
+
+               public bool IsInstance {
+                       get {
+                               foreach (MethodBase mb in Methods)
+                                       if (!mb.IsStatic)
+                                               return true;
+
+                               return false;
+                       }
+               }
+
+               public bool IsStatic {
+                       get {
+                               foreach (MethodBase mb in Methods)
+                                       if (mb.IsStatic)
+                                               return true;
+
+                               return false;
+                       }
+               }
+               
+               override public Expression DoResolve (EmitContext ec)
+               {
+                       if (!IsInstance)
+                               instance_expression = null;
+
+                       if (instance_expression != null) {
+                               instance_expression = instance_expression.DoResolve (ec);
+                               if (instance_expression == null)
+                                       return null;
+                       }
+
+                       return this;
+               }
+
+               public void ReportUsageError ()
+               {
+                       Report.Error (654, loc, "Method `" + DeclaringType + "." +
+                                     Name + "()' is referenced without parentheses");
+               }
+
+               override public void Emit (EmitContext ec)
+               {
+                       ReportUsageError ();
+               }
+
+               bool RemoveMethods (bool keep_static)
+               {
+                       ArrayList smethods = new ArrayList ();
+
+                       foreach (MethodBase mb in Methods){
+                               if (mb.IsStatic == keep_static)
+                                       smethods.Add (mb);
+                       }
+
+                       if (smethods.Count == 0)
+                               return false;
+
+                       Methods = new MethodBase [smethods.Count];
+                       smethods.CopyTo (Methods, 0);
+
+                       return true;
+               }
+               
+               /// <summary>
+               ///   Removes any instance methods from the MethodGroup, returns
+               ///   false if the resulting set is empty.
+               /// </summary>
+               public bool RemoveInstanceMethods ()
+               {
+                       return RemoveMethods (true);
+               }
+
+               /// <summary>
+               ///   Removes any static methods from the MethodGroup, returns
+               ///   false if the resulting set is empty.
+               /// </summary>
+               public bool RemoveStaticMethods ()
+               {
+                       return RemoveMethods (false);
+               }
+
+               public Expression ResolveGeneric (EmitContext ec, TypeArguments args)
+               {
+                       if (args.Resolve (ec) == false)
+                               return null;
+
+                       Type[] atypes = args.Arguments;
+
+                       int first_count = 0;
+                       MethodInfo first = null;
+
+                       ArrayList list = new ArrayList ();
+                       foreach (MethodBase mb in Methods) {
+                               MethodInfo mi = mb as MethodInfo;
+                               if ((mi == null) || !mi.HasGenericParameters)
+                                       continue;
+
+                               Type[] gen_params = mi.GetGenericArguments ();
+
+                               if (first == null) {
+                                       first = mi;
+                                       first_count = gen_params.Length;
+                               }
+
+                               if (gen_params.Length != atypes.Length)
+                                       continue;
+
+                               list.Add (mi.BindGenericParameters (atypes));
+                       }
+
+                       if (list.Count > 0) {
+                               MethodGroupExpr new_mg = new MethodGroupExpr (list, Location);
+                               new_mg.InstanceExpression = InstanceExpression;
+                               new_mg.HasTypeArguments = true;
+                               return new_mg;
+                       }
+
+                       if (first != null)
+                               Report.Error (
+                                       305, loc, "Using the generic method `{0}' " +
+                                       "requires {1} type arguments", Name,
+                                       first_count);
+                       else
+                               Report.Error (
+                                       308, loc, "The non-generic method `{0}' " +
+                                       "cannot be used with type arguments", Name);
+
+                       return null;
+               }
+       }
+
+       /// <summary>
+       ///   Fully resolved expression that evaluates to a Field
+       /// </summary>
+       public class FieldExpr : Expression, IAssignMethod, IMemoryLocation, IMemberExpr, IVariable {
+               public readonly FieldInfo FieldInfo;
+               Expression instance_expr;
+               VariableInfo variable_info;
+               
+               LocalTemporary temp;
+               bool prepared;
+               bool is_field_initializer;
+               
+               public FieldExpr (FieldInfo fi, Location l)
+               {
+                       FieldInfo = fi;
+                       eclass = ExprClass.Variable;
+                       type = TypeManager.TypeToCoreType (fi.FieldType);
+                       loc = l;
+               }
+
+               public string Name {
+                       get {
+                               return FieldInfo.Name;
+                       }
+               }
+
+               public bool IsInstance {
+                       get {
+                               return !FieldInfo.IsStatic;
+                       }
+               }
+
+               public bool IsStatic {
+                       get {
+                               return FieldInfo.IsStatic;
+                       }
+               }
+
+               public Type DeclaringType {
+                       get {
+                               return FieldInfo.DeclaringType;
+                       }
+               }
+
+               public Expression InstanceExpression {
+                       get {
+                               return instance_expr;
+                       }
+
+                       set {
+                               instance_expr = value;
+                       }
+               }
+
+               public bool IsFieldInitializer {
+                       get {
+                               return is_field_initializer;
+                       }
+
+                       set {
+                               is_field_initializer = value;
+                       }
+               }
+
+               public VariableInfo VariableInfo {
+                       get {
+                               return variable_info;
+                       }
+               }
+
+               override public Expression DoResolve (EmitContext ec)
+               {
+                       if (!FieldInfo.IsStatic){
+                               if (instance_expr == null){
+                                       //
+                                       // This can happen when referencing an instance field using
+                                       // a fully qualified type expression: TypeName.InstanceField = xxx
+                                       // 
+                                       SimpleName.Error_ObjectRefRequired (ec, loc, FieldInfo.Name);
+                                       return null;
+                               }
+
+                               // Resolve the field's instance expression while flow analysis is turned
+                               // off: when accessing a field "a.b", we must check whether the field
+                               // "a.b" is initialized, not whether the whole struct "a" is initialized.
+                               instance_expr = instance_expr.Resolve (ec, ResolveFlags.VariableOrValue |
+                                                                      ResolveFlags.DisableFlowAnalysis);
+                               if (instance_expr == null)
+                                       return null;
+                       }
+
+                       ObsoleteAttribute oa;
+                       FieldBase f = TypeManager.GetField (FieldInfo);
+                       if (f != null) {
+                               oa = f.GetObsoleteAttribute (f.Parent);
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, f.GetSignatureForError (), loc);
+                               // To be sure that type is external because we do not register generated fields
+                        } else if (!(FieldInfo.DeclaringType is TypeBuilder)) {                                
+                               oa = AttributeTester.GetMemberObsoleteAttribute (FieldInfo);
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (FieldInfo), loc);
+                       }
+
+                       if (ec.CurrentAnonymousMethod != null){
+                               if (!FieldInfo.IsStatic){
+                                       if (ec.TypeContainer is Struct){
+                                               Report.Error (1673, loc, "Can not reference instance variables in anonymous methods hosted in structs");
+                                               return null;
+                                       }
+                                       ec.CaptureField (this);
+                               } 
+                       }
+                       
+                       // If the instance expression is a local variable or parameter.
+                       IVariable var = instance_expr as IVariable;
+                       if ((var == null) || (var.VariableInfo == null))
+                               return this;
+
+                       VariableInfo vi = var.VariableInfo;
+                       if (!vi.IsFieldAssigned (ec, FieldInfo.Name, loc))
+                               return null;
+
+                       variable_info = vi.GetSubStruct (FieldInfo.Name);
+                       return this;
+               }
+
+               void Report_AssignToReadonly (bool is_instance)
+               {
+                       string msg;
+                       
+                       if (is_instance)
+                               msg = "Readonly field can not be assigned outside " +
+                               "of constructor or variable initializer";
+                       else
+                               msg = "A static readonly field can only be assigned in " +
+                               "a static constructor";
+
+                       Report.Error (is_instance ? 191 : 198, loc, msg);
+               }
+               
+               override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       IVariable var = instance_expr as IVariable;
+                       if ((var != null) && (var.VariableInfo != null))
+                               var.VariableInfo.SetFieldAssigned (ec, FieldInfo.Name);
+
+                       Expression e = DoResolve (ec);
+
+                       if (e == null)
+                               return null;
+
+                       if (!FieldInfo.IsStatic && (instance_expr.Type.IsValueType && !(instance_expr is IMemoryLocation))) {
+                               // FIXME: Provide better error reporting.
+                               Error (1612, "Cannot modify expression because it is not a variable.");
+                               return null;
+                       }
+
+                       if (!FieldInfo.IsInitOnly)
+                               return this;
+
+                       FieldBase fb = TypeManager.GetField (FieldInfo);
+                       if (fb != null)
+                               fb.SetAssigned ();
+
+                       //
+                       // InitOnly fields can only be assigned in constructors
+                       //
+
+                       if (ec.IsConstructor){
+                               if (IsStatic && !ec.IsStatic)
+                                       Report_AssignToReadonly (false);
+
+                               Type ctype;
+                               if (!is_field_initializer &&
+                                   (ec.TypeContainer.CurrentType != null))
+                                       ctype = ec.TypeContainer.CurrentType;
+                               else
+                                       ctype = ec.ContainerType;
+
+                               if (TypeManager.IsEqual (ctype, FieldInfo.DeclaringType))
+                                       return this;
+                       }
+
+                       Report_AssignToReadonly (!IsStatic);
+                       
+                       return null;
+               }
+
+               public override void CheckMarshallByRefAccess (Type container)
+               {
+                       if (!IsStatic && Type.IsValueType && !container.IsSubclassOf (TypeManager.mbr_type) && DeclaringType.IsSubclassOf (TypeManager.mbr_type)) {
+                               Report.SymbolRelatedToPreviousError (DeclaringType);
+                               Report.Error (1690, loc, "Cannot call '{0}' method, property, or indexer because it is a value type member of a marshal-by-reference class", Name);
+                       }
+               }
+
+               public bool VerifyFixed (bool is_expression)
+               {
+                       IVariable variable = instance_expr as IVariable;
+                       if ((variable == null) || !variable.VerifyFixed (true))
+                               return false;
+
+                       return true;
+               }
+               
+               public void Emit (EmitContext ec, bool leave_copy)
+               {
+                       ILGenerator ig = ec.ig;
+                       bool is_volatile = false;
+
+                       if (FieldInfo is FieldBuilder){
+                               FieldBase f = TypeManager.GetField (FieldInfo);
+                               if (f != null){
+                                       if ((f.ModFlags & Modifiers.VOLATILE) != 0)
+                                               is_volatile = true;
+                                       
+                                       f.status |= Field.Status.USED;
+                               }
+                       } 
+                       
+                       if (FieldInfo.IsStatic){
+                               if (is_volatile)
+                                       ig.Emit (OpCodes.Volatile);
+                               
+                               ig.Emit (OpCodes.Ldsfld, FieldInfo);
+                       } else {
+                               if (!prepared)
+                                       EmitInstance (ec);
+
+                               if (is_volatile)
+                                       ig.Emit (OpCodes.Volatile);
+
+                               ig.Emit (OpCodes.Ldfld, FieldInfo);
+                       }
+
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               if (!FieldInfo.IsStatic) {
+                                       temp = new LocalTemporary (ec, this.Type);
+                                       temp.Store (ec);
+                               }
+                       }
+               }
+
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+               {
+                       FieldAttributes fa = FieldInfo.Attributes;
+                       bool is_static = (fa & FieldAttributes.Static) != 0;
+                       bool is_readonly = (fa & FieldAttributes.InitOnly) != 0;
+                       ILGenerator ig = ec.ig;
+                       prepared = prepare_for_load;
+
+                       if (is_readonly && !ec.IsConstructor){
+                               Report_AssignToReadonly (!is_static);
+                               return;
+                       }
+
+                       if (!is_static) {
+                               EmitInstance (ec);
+                               if (prepare_for_load)
+                                       ig.Emit (OpCodes.Dup);
+                       }
+
+                       source.Emit (ec);
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               if (!FieldInfo.IsStatic) {
+                                       temp = new LocalTemporary (ec, this.Type);
+                                       temp.Store (ec);
+                               }
+                       }
+
+                       if (FieldInfo is FieldBuilder){
+                               FieldBase f = TypeManager.GetField (FieldInfo);
+                               if (f != null){
+                                       if ((f.ModFlags & Modifiers.VOLATILE) != 0)
+                                               ig.Emit (OpCodes.Volatile);
+                                       
+                                       f.status |= Field.Status.ASSIGNED;
+                               }
+                       } 
+
+                       if (is_static)
+                               ig.Emit (OpCodes.Stsfld, FieldInfo);
+                       else 
+                               ig.Emit (OpCodes.Stfld, FieldInfo);
+                       
+                       if (temp != null)
+                               temp.Emit (ec);
+               }
+
+               void EmitInstance (EmitContext ec)
+               {
+                       if (instance_expr.Type.IsValueType) {
+                               if (instance_expr is IMemoryLocation) {
+                                       ((IMemoryLocation) instance_expr).AddressOf (ec, AddressOp.LoadStore);
+                               } else {
+                                       LocalTemporary t = new LocalTemporary (ec, instance_expr.Type);
+                                       instance_expr.Emit (ec);
+                                       t.Store (ec);
+                                       t.AddressOf (ec, AddressOp.Store);
+                               }
+                       } else
+                               instance_expr.Emit (ec);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       Emit (ec, false);
+               }
+
+               public void AddressOf (EmitContext ec, AddressOp mode)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       if (FieldInfo is FieldBuilder){
+                               FieldBase f = TypeManager.GetField (FieldInfo);
+                               if (f != null){
+                                       if ((f.ModFlags & Modifiers.VOLATILE) != 0){
+                                               Error (676, "volatile variable: can not take its address, or pass as ref/out parameter");
+                                               return;
+                                       }
+                                       
+                                       if ((mode & AddressOp.Store) != 0)
+                                               f.status |= Field.Status.ASSIGNED;
+                                       if ((mode & AddressOp.Load) != 0)
+                                               f.status |= Field.Status.USED;
+                               }
+                       } 
+
+                       //
+                       // Handle initonly fields specially: make a copy and then
+                       // get the address of the copy.
+                       //
+                       bool need_copy;
+                       if (FieldInfo.IsInitOnly){
+                               need_copy = true;
+                               if (ec.IsConstructor){
+                                       if (FieldInfo.IsStatic){
+                                               if (ec.IsStatic)
+                                                       need_copy = false;
+                                       } else
+                                               need_copy = false;
+                               }
+                       } else
+                               need_copy = false;
+                       
+                       if (need_copy){
+                               LocalBuilder local;
+                               Emit (ec);
+                               local = ig.DeclareLocal (type);
+                               ig.Emit (OpCodes.Stloc, local);
+                               ig.Emit (OpCodes.Ldloca, local);
+                               return;
+                       }
+
+
+                       if (FieldInfo.IsStatic){
+                               ig.Emit (OpCodes.Ldsflda, FieldInfo);
+                       } else {
+                               EmitInstance (ec);
+                               ig.Emit (OpCodes.Ldflda, FieldInfo);
+                       }
+               }
+       }
+
+       //
+       // A FieldExpr whose address can not be taken
+       //
+       public class FieldExprNoAddress : FieldExpr, IMemoryLocation {
+               public FieldExprNoAddress (FieldInfo fi, Location loc) : base (fi, loc)
+               {
+               }
+               
+               public new void AddressOf (EmitContext ec, AddressOp mode)
+               {
+                       Report.Error (-215, "Report this: Taking the address of a remapped parameter not supported");
+               }
+       }
+       
+       /// <summary>
+       ///   Expression that evaluates to a Property.  The Assign class
+       ///   might set the `Value' expression if we are in an assignment.
+       ///
+       ///   This is not an LValue because we need to re-write the expression, we
+       ///   can not take data from the stack and store it.  
+       /// </summary>
+       public class PropertyExpr : ExpressionStatement, IAssignMethod, IMemberExpr {
+               public readonly PropertyInfo PropertyInfo;
+
+               //
+               // This is set externally by the  `BaseAccess' class
+               //
+               public bool IsBase;
+               MethodInfo getter, setter;
+               bool is_static;
+               
+               Expression instance_expr;
+               LocalTemporary temp;
+               bool prepared;
+
+               public PropertyExpr (EmitContext ec, PropertyInfo pi, Location l)
+               {
+                       PropertyInfo = pi;
+                       eclass = ExprClass.PropertyAccess;
+                       is_static = false;
+                       loc = l;
+
+                       type = TypeManager.TypeToCoreType (pi.PropertyType);
+
+                       ResolveAccessors (ec);
+               }
+
+               public string Name {
+                       get {
+                               return PropertyInfo.Name;
+                       }
+               }
+
+               public bool IsInstance {
+                       get {
+                               return !is_static;
+                       }
+               }
+
+               public bool IsStatic {
+                       get {
+                               return is_static;
+                       }
+               }
+               
+               public Type DeclaringType {
+                       get {
+                               return PropertyInfo.DeclaringType;
+                       }
+               }
+
+               //
+               // The instance expression associated with this expression
+               //
+               public Expression InstanceExpression {
+                       set {
+                               instance_expr = value;
+                       }
+
+                       get {
+                               return instance_expr;
+                       }
+               }
+
+               public bool VerifyAssignable ()
+               {
+                       if (setter == null) {
+                               Report.Error (200, loc, 
+                                             "The property `" + PropertyInfo.Name +
+                                             "' can not be assigned to, as it has not set accessor");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               void FindAccessors (Type invocation_type)
+               {
+                       BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic |
+                               BindingFlags.Static | BindingFlags.Instance |
+                               BindingFlags.DeclaredOnly;
+
+                       Type current = PropertyInfo.DeclaringType;
+                       for (; current != null; current = current.BaseType) {
+                               MemberInfo[] group = TypeManager.MemberLookup (
+                                       invocation_type, invocation_type, current,
+                                       MemberTypes.Property, flags, PropertyInfo.Name, null);
+
+                               if (group == null)
+                                       continue;
+
+                               if (group.Length != 1)
+                                       // Oooops, can this ever happen ?
+                                       return;
+
+                               PropertyInfo pi = (PropertyInfo) group [0];
+
+                               if (getter == null)
+                                       getter = pi.GetGetMethod (true);;
+
+                               if (setter == null)
+                                       setter = pi.GetSetMethod (true);;
+
+                               MethodInfo accessor = getter != null ? getter : setter;
+
+                               if (!accessor.IsVirtual)
+                                       return;
+                       }
+               }
+
+               //
+               // We also perform the permission checking here, as the PropertyInfo does not
+               // hold the information for the accessibility of its setter/getter
+               //
+               void ResolveAccessors (EmitContext ec)
+               {
+                       FindAccessors (ec.ContainerType);
+
+                       is_static = getter != null ? getter.IsStatic : setter.IsStatic;
+               }
+
+               bool InstanceResolve (EmitContext ec, bool must_do_cs1540_check)
+               {
+                       if ((instance_expr == null) && ec.IsStatic && !is_static) {
+                               SimpleName.Error_ObjectRefRequired (ec, loc, PropertyInfo.Name);
+                               return false;
+                       }
+
+                       if (instance_expr != null) {
+                               instance_expr = instance_expr.DoResolve (ec);
+                               if (instance_expr == null)
+                                       return false;
+
+                               instance_expr.CheckMarshallByRefAccess (ec.ContainerType);
+                       }
+
+                       if (must_do_cs1540_check && (instance_expr != null)) {
+                               if ((instance_expr.Type != ec.ContainerType) &&
+                                   ec.ContainerType.IsSubclassOf (instance_expr.Type)) {
+                                       Report.Error (1540, loc, "Cannot access protected member `" +
+                                                     PropertyInfo.DeclaringType + "." + PropertyInfo.Name + 
+                                                     "' via a qualifier of type `" +
+                                                     TypeManager.CSharpName (instance_expr.Type) +
+                                                     "'; the qualifier must be of type `" +
+                                                     TypeManager.CSharpName (ec.ContainerType) +
+                                                     "' (or derived from it)");
+                                       return false;
+                               }
+                       }
+
+                       return true;
+               }
+               
+               override public Expression DoResolve (EmitContext ec)
+               {
+                       if (getter != null){
+                               if (TypeManager.GetArgumentTypes (getter).Length != 0){
+                                       Report.Error (
+                                               117, loc, "`{0}' does not contain a " +
+                                               "definition for `{1}'.", getter.DeclaringType,
+                                               Name);
+                                       return null;
+                               }
+                       }
+
+                       if (getter == null){
+                               //
+                               // The following condition happens if the PropertyExpr was
+                               // created, but is invalid (ie, the property is inaccessible),
+                               // and we did not want to embed the knowledge about this in
+                               // the caller routine.  This only avoids double error reporting.
+                               //
+                               if (setter == null)
+                                       return null;
+                               
+                               Report.Error (154, loc, 
+                                             "The property `" + PropertyInfo.Name +
+                                             "' can not be used in " +
+                                             "this context because it lacks a get accessor");
+                               return null;
+                       } 
+
+                       bool must_do_cs1540_check;
+                       if (!IsAccessorAccessible (ec.ContainerType, getter, out must_do_cs1540_check)) {
+                               Report.Error (122, loc, "'{0}.get' is inaccessible due to its protection level", PropertyInfo.Name);
+                               return null;
+                       }
+
+                       if (!InstanceResolve (ec, must_do_cs1540_check))
+                               return null;
+
+                       //
+                       // Only base will allow this invocation to happen.
+                       //
+                       if (IsBase && getter.IsAbstract){
+                               Report.Error (205, loc, "Cannot call an abstract base property: " +
+                                             PropertyInfo.DeclaringType + "." +PropertyInfo.Name);
+                               return null;
+                       }
+
+                       return this;
+               }
+
+               override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       if (setter == null){
+                               //
+                               // The following condition happens if the PropertyExpr was
+                               // created, but is invalid (ie, the property is inaccessible),
+                               // and we did not want to embed the knowledge about this in
+                               // the caller routine.  This only avoids double error reporting.
+                               //
+                               if (getter == null)
+                                       return null;
+                               
+                               Report.Error (154, loc, 
+                                             "The property `" + PropertyInfo.Name +
+                                             "' can not be used in " +
+                                             "this context because it lacks a set accessor");
+                               return null;
+                       }
+
+                       if (TypeManager.GetArgumentTypes (setter).Length != 1){
+                               Report.Error (
+                                       117, loc, "`{0}' does not contain a " +
+                                       "definition for `{1}'.", getter.DeclaringType,
+                                       Name);
+                               return null;
+                       }
+
+                       bool must_do_cs1540_check;
+                       if (!IsAccessorAccessible (ec.ContainerType, setter, out must_do_cs1540_check)) {
+                               Report.Error (122, loc, "'{0}.set' is inaccessible due to its protection level", PropertyInfo.Name);
+                               return null;
+                       }
+
+                       if (!InstanceResolve (ec, must_do_cs1540_check))
+                               return null;
+                       
+                       //
+                       // Only base will allow this invocation to happen.
+                       //
+                       if (IsBase && setter.IsAbstract){
+                               Report.Error (205, loc, "Cannot call an abstract base property: " +
+                                             PropertyInfo.DeclaringType + "." +PropertyInfo.Name);
+                               return null;
+                       }
+
+                       //
+                       // Check that we are not making changes to a temporary memory location
+                       //
+                       if (instance_expr != null && instance_expr.Type.IsValueType && !(instance_expr is IMemoryLocation)) {
+                               // FIXME: Provide better error reporting.
+                               Error (1612, "Cannot modify expression because it is not a variable.");
+                               return null;
+                       }
+
+                       return this;
+               }
+
+
+               
+               public override void Emit (EmitContext ec)
+               {
+                       Emit (ec, false);
+               }
+               
+               void EmitInstance (EmitContext ec)
+               {
+                       if (is_static)
+                               return;
+
+                       if (instance_expr.Type.IsValueType) {
+                               if (instance_expr is IMemoryLocation) {
+                                       ((IMemoryLocation) instance_expr).AddressOf (ec, AddressOp.LoadStore);
+                               } else {
+                                       LocalTemporary t = new LocalTemporary (ec, instance_expr.Type);
+                                       instance_expr.Emit (ec);
+                                       t.Store (ec);
+                                       t.AddressOf (ec, AddressOp.Store);
+                               }
+                       } else
+                               instance_expr.Emit (ec);
+                       
+                       if (prepared)
+                               ec.ig.Emit (OpCodes.Dup);
+               }
+
+               
+               public void Emit (EmitContext ec, bool leave_copy)
+               {
+                       if (!prepared)
+                               EmitInstance (ec);
+                       
+                       //
+                       // Special case: length of single dimension array property is turned into ldlen
+                       //
+                       if ((getter == TypeManager.system_int_array_get_length) ||
+                           (getter == TypeManager.int_array_get_length)){
+                               Type iet = instance_expr.Type;
+
+                               //
+                               // System.Array.Length can be called, but the Type does not
+                               // support invoking GetArrayRank, so test for that case first
+                               //
+                               if (iet != TypeManager.array_type && (iet.GetArrayRank () == 1)) {
+                                       ec.ig.Emit (OpCodes.Ldlen);
+                                       ec.ig.Emit (OpCodes.Conv_I4);
+                                       return;
+                               }
+                       }
+
+                       Invocation.EmitCall (ec, IsBase, IsStatic, new EmptyAddressOf (), getter, null, loc);
+                       
+                       if (!leave_copy)
+                               return;
+                       
+                       ec.ig.Emit (OpCodes.Dup);
+                       if (!is_static) {
+                               temp = new LocalTemporary (ec, this.Type);
+                               temp.Store (ec);
+                       }
+               }
+
+               //
+               // Implements the IAssignMethod interface for assignments
+               //
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+               {
+                       prepared = prepare_for_load;
+                       
+                       EmitInstance (ec);
+
+                       source.Emit (ec);
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               if (!is_static) {
+                                       temp = new LocalTemporary (ec, this.Type);
+                                       temp.Store (ec);
+                               }
+                       }
+                       
+                       ArrayList args = new ArrayList (1);
+                       args.Add (new Argument (new EmptyAddressOf (), Argument.AType.Expression));
+                       
+                       Invocation.EmitCall (ec, IsBase, IsStatic, new EmptyAddressOf (), setter, args, loc);
+                       
+                       if (temp != null)
+                               temp.Emit (ec);
+               }
+
+               override public void EmitStatement (EmitContext ec)
+               {
+                       Emit (ec);
+                       ec.ig.Emit (OpCodes.Pop);
+               }
+       }
+
+       /// <summary>
+       ///   Fully resolved expression that evaluates to an Event
+       /// </summary>
+       public class EventExpr : Expression, IMemberExpr {
+               public readonly EventInfo EventInfo;
+               Expression instance_expr;
+
+               bool is_static;
+               MethodInfo add_accessor, remove_accessor;
+               
+               public EventExpr (EventInfo ei, Location loc)
+               {
+                       EventInfo = ei;
+                       this.loc = loc;
+                       eclass = ExprClass.EventAccess;
+
+                       add_accessor = TypeManager.GetAddMethod (ei);
+                       remove_accessor = TypeManager.GetRemoveMethod (ei);
+                       
+                       if (add_accessor.IsStatic || remove_accessor.IsStatic)
+                               is_static = true;
+
+                       if (EventInfo is MyEventBuilder){
+                               MyEventBuilder eb = (MyEventBuilder) EventInfo;
+                               type = eb.EventType;
+                               eb.SetUsed ();
+                       } else
+                               type = EventInfo.EventHandlerType;
+               }
+
+               public string Name {
+                       get {
+                               return EventInfo.Name;
+                       }
+               }
+
+               public bool IsInstance {
+                       get {
+                               return !is_static;
+                       }
+               }
+
+               public bool IsStatic {
+                       get {
+                               return is_static;
+                       }
+               }
+
+               public Type DeclaringType {
+                       get {
+                               return EventInfo.DeclaringType;
+                       }
+               }
+
+               public Expression InstanceExpression {
+                       get {
+                               return instance_expr;
+                       }
+
+                       set {
+                               instance_expr = value;
+                       }
+               }
+
+               bool InstanceResolve (EmitContext ec, bool must_do_cs1540_check)
+               {
+                       if ((instance_expr == null) && ec.IsStatic && !is_static) {
+                               SimpleName.Error_ObjectRefRequired (ec, loc, EventInfo.Name);
+                               return false;
+                       }
+
+                       if (instance_expr != null) {
+                               instance_expr = instance_expr.DoResolve (ec);
+                               if (instance_expr == null)
+                                       return false;
+                       }
+
+                       //
+                       // This is using the same mechanism as the CS1540 check in PropertyExpr.
+                       // However, in the Event case, we reported a CS0122 instead.
+                       //
+                       if (must_do_cs1540_check && (instance_expr != null)) {
+                               if ((instance_expr.Type != ec.ContainerType) &&
+                                       ec.ContainerType.IsSubclassOf (instance_expr.Type)) {
+                                       Report.Error (122, loc, "'{0}' is inaccessible due to its protection level",
+                                               DeclaringType.Name + "." + EventInfo.Name);
+
+                                       return false;
+                               }
+                       }
+
+                       return true;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if (instance_expr != null) {
+                               instance_expr = instance_expr.DoResolve (ec);
+                               if (instance_expr == null)
+                                       return null;
+                       }
+
+                       bool must_do_cs1540_check;
+                       if (!(IsAccessorAccessible (ec.ContainerType, add_accessor, out must_do_cs1540_check)
+                                   && IsAccessorAccessible (ec.ContainerType, remove_accessor, out must_do_cs1540_check))) {
+                               
+                               Report.Error (122, loc, "'{0}' is inaccessible due to its protection level",
+                                               DeclaringType.Name + "." + EventInfo.Name);
+                               return null;
+                       }
+
+                       if (!InstanceResolve (ec, must_do_cs1540_check))
+                               return null;
+                       
+                       return this;
+               }               
+
+               public override void Emit (EmitContext ec)
+               {
+                       if (instance_expr is This)
+                               Report.Error (79, loc, "The event `{0}' can only appear on the left hand side of += or -=, try calling the actual delegate");
+                       else
+                               Report.Error (70, loc, "The event `{0}' can only appear on the left hand side of += or -= "+
+                                             "(except on the defining type)", Name);
+               }
+
+               public void EmitAddOrRemove (EmitContext ec, Expression source)
+               {
+                       BinaryDelegate source_del = (BinaryDelegate) source;
+                       Expression handler = source_del.Right;
+                       
+                       Argument arg = new Argument (handler, Argument.AType.Expression);
+                       ArrayList args = new ArrayList ();
+                               
+                       args.Add (arg);
+                       
+                       if (source_del.IsAddition)
+                               Invocation.EmitCall (
+                                       ec, false, IsStatic, instance_expr, add_accessor, args, loc);
+                       else
+                               Invocation.EmitCall (
+                                       ec, false, IsStatic, instance_expr, remove_accessor, args, loc);
+               }
+       }
+}      
diff --git a/mcs/bmcs/enum.cs b/mcs/bmcs/enum.cs
new file mode 100644 (file)
index 0000000..1ae1615
--- /dev/null
@@ -0,0 +1,811 @@
+//
+// enum.cs: Enum handling.
+//
+// Author: Miguel de Icaza (miguel@gnu.org)
+//         Ravi Pratap     (ravi@ximian.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Globalization;
+using System.Xml;
+
+namespace Mono.CSharp {
+
+       class EnumMember: MemberCore {
+               static string[] attribute_targets = new string [] { "field" };
+
+               Enum parent_enum;
+               public FieldBuilder builder;
+               internal readonly Expression Type;
+
+               public EnumMember (Enum parent_enum, Expression expr, string name,
+                                  Location loc, Attributes attrs):
+                       base (null, new MemberName (name), attrs, loc)
+               {
+                       this.parent_enum = parent_enum;
+                       this.ModFlags = parent_enum.ModFlags;
+                       this.Type = expr;
+               }
+
+               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type == TypeManager.marshal_as_attr_type) {
+                               UnmanagedMarshal marshal = a.GetMarshal (this);
+                               if (marshal != null) {
+                                       builder.SetMarshal (marshal);
+                               }
+                                       return;
+                               }
+
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
+                               a.Error_InvalidSecurityParent ();
+                               return;
+                       }
+
+                       builder.SetCustomAttribute (cb);
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Field;
+                       }
+               }
+
+               public void DefineMember (TypeBuilder tb)
+               {
+                       FieldAttributes attr = FieldAttributes.Public | FieldAttributes.Static
+                               | FieldAttributes.Literal;
+                       
+                       builder = tb.DefineField (Name, tb, attr);
+               }
+
+               public override bool Define ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void Emit (EmitContext ec)
+               {
+                       if (OptAttributes != null)
+                               OptAttributes.Emit (ec, this); 
+
+                       Emit ();
+               }
+
+               public override string GetSignatureForError()
+               {
+                       return String.Concat (parent_enum.GetSignatureForError (), '.', base.GetSignatureForError ());
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+
+               protected override bool VerifyClsCompliance(DeclSpace ds)
+               {
+                       // Because parent is TypeContainer and we have only DeclSpace parent.
+                       // Parameter replacing is required
+                       return base.VerifyClsCompliance (parent_enum);
+               }
+
+               // There is no base type
+               protected override void VerifyObsoleteAttribute()
+               {
+               }
+
+               public override string DocCommentHeader {
+                       get { return "F:"; }
+               }
+       }
+
+       /// <summary>
+       ///   Enumeration container
+       /// </summary>
+       public class Enum : DeclSpace {
+               public ArrayList ordered_enums;
+               
+               public Expression BaseType;
+               
+               public Type UnderlyingType;
+
+               Hashtable member_to_location;
+
+               //
+               // This is for members that have been defined
+               //
+               Hashtable member_to_value;
+
+               //
+               // This is used to mark members we're currently defining
+               //
+               Hashtable in_transit;
+               
+               ArrayList field_builders;
+               
+               public const int AllowedModifiers =
+                       Modifiers.NEW |
+                       Modifiers.PUBLIC |
+                       Modifiers.PROTECTED |
+                       Modifiers.INTERNAL |
+                       Modifiers.PRIVATE;
+
+               public Enum (NamespaceEntry ns, TypeContainer parent, Expression type,
+                            int mod_flags, MemberName name, Attributes attrs, Location l)
+                       : base (ns, parent, name, attrs, l)
+               {
+                       this.BaseType = type;
+                       ModFlags = Modifiers.Check (AllowedModifiers, mod_flags,
+                                                   IsTopLevel ? Modifiers.INTERNAL : Modifiers.PRIVATE, l);
+
+                       ordered_enums = new ArrayList ();
+                       member_to_location = new Hashtable ();
+                       member_to_value = new Hashtable ();
+                       in_transit = new Hashtable ();
+                       field_builders = new ArrayList ();
+               }
+
+               /// <summary>
+               ///   Adds @name to the enumeration space, with @expr
+               ///   being its definition.  
+               /// </summary>
+               public void AddEnumMember (string name, Expression expr, Location loc, Attributes opt_attrs, string documentation)
+               {
+                       if (name == "value__") {
+                               Report.Error (76, loc, "An item in an enumeration can't have an identifier `value__'");
+                               return;
+                       }
+
+                       EnumMember em = new EnumMember (this, expr, name, loc, opt_attrs);
+                       em.DocComment = documentation;
+                       if (!AddToContainer (em, false, name, ""))
+                               return;
+
+
+                       // TODO: can be almost deleted
+                       ordered_enums.Add (name);
+                       member_to_location.Add (name, loc);
+               }
+
+               //
+               // This is used by corlib compilation: we map from our
+               // type to a type that is consumable by the DefineField
+               //
+               Type MapToInternalType (Type t)
+               {
+                       if (t == TypeManager.int32_type)
+                               return typeof (int);
+                       if (t == TypeManager.int64_type)
+                               return typeof (long);
+                       if (t == TypeManager.uint32_type)
+                               return typeof (uint);
+                       if (t == TypeManager.uint64_type)
+                               return typeof (ulong);
+                       if (t == TypeManager.float_type)
+                               return typeof (float);
+                       if (t == TypeManager.double_type)
+                               return typeof (double);
+                       if (t == TypeManager.byte_type)
+                               return typeof (byte);
+                       if (t == TypeManager.sbyte_type)
+                               return typeof (sbyte);
+                       if (t == TypeManager.char_type)
+                               return typeof (char);
+                       if (t == TypeManager.short_type)
+                               return typeof (short);
+                       if (t == TypeManager.ushort_type)
+                               return typeof (ushort);
+
+                       throw new Exception ();
+               }
+               
+               public override TypeBuilder DefineType ()
+               {
+                       if (TypeBuilder != null)
+                               return TypeBuilder;
+
+                       TypeAttributes attr = Modifiers.TypeAttr (ModFlags, IsTopLevel);
+
+                       ec = new EmitContext (this, this, Location, null, null, ModFlags, false);
+
+                       attr |= TypeAttributes.Class | TypeAttributes.Sealed;
+
+                       if (!(BaseType is TypeLookupExpression)) {
+                               Report.Error (1008, Location,
+                                             "Type byte, sbyte, short, ushort, int, uint, " +
+                                             "long, or ulong expected (got: `{0}')", BaseType);
+                               return null;
+                       }
+
+                       TypeExpr texpr = ResolveTypeExpr (BaseType, Location);
+                       if (texpr == null)
+                               return null;
+
+                       UnderlyingType = texpr.Type;
+
+                       if (UnderlyingType != TypeManager.int32_type &&
+                           UnderlyingType != TypeManager.uint32_type &&
+                           UnderlyingType != TypeManager.int64_type &&
+                           UnderlyingType != TypeManager.uint64_type &&
+                           UnderlyingType != TypeManager.short_type &&
+                           UnderlyingType != TypeManager.ushort_type &&
+                           UnderlyingType != TypeManager.byte_type  &&
+                           UnderlyingType != TypeManager.sbyte_type) {
+                               Report.Error (1008, Location,
+                                             "Type byte, sbyte, short, ushort, int, uint, " +
+                                             "long, or ulong expected (got: " +
+                                             TypeManager.CSharpName (UnderlyingType) + ")");
+                               return null;
+                       }
+
+                       if (IsTopLevel) {
+                               if (TypeManager.NamespaceClash (Name, Location))
+                                       return null;
+                               
+                               ModuleBuilder builder = CodeGen.Module.Builder;
+
+                               TypeBuilder = builder.DefineType (Name, attr, TypeManager.enum_type);
+                       } else {
+                               TypeBuilder builder = Parent.TypeBuilder;
+
+                               TypeBuilder = builder.DefineNestedType (
+                                       Basename, attr, TypeManager.enum_type);
+                       }
+
+                       //
+                       // Call MapToInternalType for corlib
+                       //
+                       TypeBuilder.DefineField ("value__", UnderlyingType,
+                                                FieldAttributes.Public | FieldAttributes.SpecialName
+                                                | FieldAttributes.RTSpecialName);
+
+                       TypeManager.AddEnumType (Name, TypeBuilder, this);
+
+                       return TypeBuilder;
+               }
+
+               bool IsValidEnumConstant (Expression e)
+               {
+                       if (!(e is Constant))
+                               return false;
+
+                       if (e is IntConstant || e is UIntConstant || e is LongConstant ||
+                           e is ByteConstant || e is SByteConstant || e is ShortConstant ||
+                           e is UShortConstant || e is ULongConstant || e is EnumConstant ||
+                           e is CharConstant)
+                               return true;
+                       else
+                               return false;
+               }
+
+               object GetNextDefaultValue (object default_value)
+               {
+                       if (UnderlyingType == TypeManager.int32_type) {
+                               int i = (int) default_value;
+                               
+                               if (i < System.Int32.MaxValue)
+                                       return ++i;
+                               else
+                                       return null;
+                       } else if (UnderlyingType == TypeManager.uint32_type) {
+                               uint i = (uint) default_value;
+
+                               if (i < System.UInt32.MaxValue)
+                                       return ++i;
+                               else
+                                       return null;
+                       } else if (UnderlyingType == TypeManager.int64_type) {
+                               long i = (long) default_value;
+
+                               if (i < System.Int64.MaxValue)
+                                       return ++i;
+                               else
+                                       return null;
+                       } else if (UnderlyingType == TypeManager.uint64_type) {
+                               ulong i = (ulong) default_value;
+
+                               if (i < System.UInt64.MaxValue)
+                                       return ++i;
+                               else
+                                       return null;
+                       } else if (UnderlyingType == TypeManager.short_type) {
+                               short i = (short) default_value;
+
+                               if (i < System.Int16.MaxValue)
+                                       return ++i;
+                               else
+                                       return null;
+                       } else if (UnderlyingType == TypeManager.ushort_type) {
+                               ushort i = (ushort) default_value;
+
+                               if (i < System.UInt16.MaxValue)
+                                       return ++i;
+                               else
+                                       return null;
+                       } else if (UnderlyingType == TypeManager.byte_type) {
+                               byte i = (byte) default_value;
+
+                               if (i < System.Byte.MaxValue)
+                                       return ++i;
+                               else
+                                       return null;
+                       } else if (UnderlyingType == TypeManager.sbyte_type) {
+                               sbyte i = (sbyte) default_value;
+
+                               if (i < System.SByte.MaxValue)
+                                       return ++i;
+                               else
+                                       return null;
+                       }
+
+                       return null;
+               }
+
+               void Error_ConstantValueCannotBeConverted (object val, Location loc)
+               {
+                       if (val is Constant)
+                               Report.Error (31, loc, "Constant value '" + ((Constant) val).AsString () +
+                                             "' cannot be converted" +
+                                             " to a " + TypeManager.CSharpName (UnderlyingType));
+                       else 
+                               Report.Error (31, loc, "Constant value '" + val +
+                                             "' cannot be converted" +
+                                             " to a " + TypeManager.CSharpName (UnderlyingType));
+                       return;
+               }
+
+               /// <summary>
+               ///  Determines if a standard implicit conversion exists from
+               ///  expr_type to target_type
+               /// </summary>
+               public static bool ImplicitConversionExists (Type expr_type, Type target_type)
+               {
+                       expr_type = TypeManager.TypeToCoreType (expr_type);
+
+                       if (expr_type == TypeManager.void_type)
+                               return false;
+                       
+                       if (expr_type == target_type)
+                               return true;
+
+                       // First numeric conversions 
+
+                       if (expr_type == TypeManager.sbyte_type){
+                               //
+                               // From sbyte to short, int, long, float, double.
+                               //
+                               if ((target_type == TypeManager.int32_type) || 
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type)  ||
+                                   (target_type == TypeManager.short_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                               
+                       } else if (expr_type == TypeManager.byte_type){
+                               //
+                               // From byte to short, ushort, int, uint, long, ulong, float, double
+                               // 
+                               if ((target_type == TypeManager.short_type) ||
+                                   (target_type == TypeManager.ushort_type) ||
+                                   (target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.uint32_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+       
+                       } else if (expr_type == TypeManager.short_type){
+                               //
+                               // From short to int, long, float, double
+                               // 
+                               if ((target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                       
+                       } else if (expr_type == TypeManager.ushort_type){
+                               //
+                               // From ushort to int, uint, long, ulong, float, double
+                               //
+                               if ((target_type == TypeManager.uint32_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                   
+                       } else if (expr_type == TypeManager.int32_type){
+                               //
+                               // From int to long, float, double
+                               //
+                               if ((target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                       
+                       } else if (expr_type == TypeManager.uint32_type){
+                               //
+                               // From uint to long, ulong, float, double
+                               //
+                               if ((target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                       
+                       } else if ((expr_type == TypeManager.uint64_type) ||
+                                  (expr_type == TypeManager.int64_type)) {
+                               //
+                               // From long/ulong to float, double
+                               //
+                               if ((target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+                                   
+                       } else if (expr_type == TypeManager.char_type){
+                               //
+                               // From char to ushort, int, uint, long, ulong, float, double
+                               // 
+                               if ((target_type == TypeManager.ushort_type) ||
+                                   (target_type == TypeManager.int32_type) ||
+                                   (target_type == TypeManager.uint32_type) ||
+                                   (target_type == TypeManager.uint64_type) ||
+                                   (target_type == TypeManager.int64_type) ||
+                                   (target_type == TypeManager.float_type) ||
+                                   (target_type == TypeManager.double_type) ||
+                                   (target_type == TypeManager.decimal_type))
+                                       return true;
+
+                       } else if (expr_type == TypeManager.float_type){
+                               //
+                               // float to double
+                               //
+                               if (target_type == TypeManager.double_type)
+                                       return true;
+                       }       
+                       
+                       return false;
+               }
+
+               //
+               // Horrible, horrible.  But there is no other way we can pass the EmitContext
+               // to the recursive definition triggered by the evaluation of a forward
+               // expression
+               //
+               static EmitContext current_ec = null;
+               
+               /// <summary>
+               ///  This is used to lookup the value of an enum member. If the member is undefined,
+               ///  it attempts to define it and return its value
+               /// </summary>
+               public object LookupEnumValue (EmitContext ec, string name, Location loc)
+               {
+                       
+                       object default_value = null;
+                       Constant c = null;
+
+                       default_value = member_to_value [name];
+
+                       if (default_value != null)
+                               return default_value;
+
+                       //
+                       // This may happen if we're calling a method in System.Enum, for instance
+                       // Enum.IsDefined().
+                       //
+                       if (!defined_names.Contains (name))
+                               return null;
+
+                       if (in_transit.Contains (name)) {
+                               Report.Error (110, loc, "The evaluation of the constant value for `" +
+                                             Name + "." + name + "' involves a circular definition.");
+                               return null;
+                       }
+
+                       //
+                       // So if the above doesn't happen, we have a member that is undefined
+                       // We now proceed to define it 
+                       //
+                       Expression val = this [name];
+
+                       if (val == null) {
+                               
+                               int idx = ordered_enums.IndexOf (name);
+
+                               if (idx == 0)
+                                       default_value = 0;
+                               else {
+                                       for (int i = 0; i < idx; ++i) {
+                                               string n = (string) ordered_enums [i];
+                                               Location m_loc = (Mono.CSharp.Location)
+                                                       member_to_location [n];
+                                               in_transit.Add (name, true);
+
+                                               EmitContext old_ec = current_ec;
+                                               current_ec = ec;
+                       
+                                               default_value = LookupEnumValue (ec, n, m_loc);
+
+                                               current_ec = old_ec;
+                                               
+                                               in_transit.Remove (name);
+                                               if (default_value == null)
+                                                       return null;
+                                       }
+                                       
+                                       default_value = GetNextDefaultValue (default_value);
+                               }
+                               
+                       } else {
+                               bool old = ec.InEnumContext;
+                               ec.InEnumContext = true;
+                               in_transit.Add (name, true);
+
+                               EmitContext old_ec = current_ec;
+                               current_ec = ec;
+                               val = val.Resolve (ec);
+                               current_ec = old_ec;
+                               
+                               in_transit.Remove (name);
+                               ec.InEnumContext = old;
+
+                               if (val == null)
+                                       return null;
+
+                               if (!IsValidEnumConstant (val)) {
+                                       Report.Error (
+                                               1008, loc,
+                                               "Type byte, sbyte, short, ushort, int, uint, long, or " +
+                                               "ulong expected (have: " + val + ")");
+                                       return null;
+                               }
+
+                               c = (Constant) val;
+                               default_value = c.GetValue ();
+
+                               if (default_value == null) {
+                                       Error_ConstantValueCannotBeConverted (c, loc);
+                                       return null;
+                               }
+
+                               if (val is EnumConstant){
+                                       Type etype = TypeManager.EnumToUnderlying (c.Type);
+                                       
+                                       if (!ImplicitConversionExists (etype, UnderlyingType)){
+                                               Convert.Error_CannotImplicitConversion (
+                                                       loc, c.Type, UnderlyingType);
+                                               return null;
+                                       }
+                               }
+                       }
+
+                       EnumMember em = (EnumMember) defined_names [name];
+                       em.DefineMember (TypeBuilder);
+
+                       bool fail;
+                       default_value = TypeManager.ChangeType (default_value, UnderlyingType, out fail);
+                       if (fail){
+                               Error_ConstantValueCannotBeConverted (c, loc);
+                               return null;
+                       }
+
+                       em.builder.SetConstant (default_value);
+                       field_builders.Add (em.builder);
+                       member_to_value [name] = default_value;
+
+                       if (!TypeManager.RegisterFieldValue (em.builder, default_value))
+                               return null;
+
+                       return default_value;
+               }
+
+               public override bool DefineMembers (TypeContainer parent)
+               {
+                       return true;
+               }
+               
+               public override bool Define ()
+               {
+                       //
+                       // If there was an error during DefineEnum, return
+                       //
+                       if (TypeBuilder == null)
+                               return false;
+
+                       ec = new EmitContext (this, this, Location, null, UnderlyingType, ModFlags, false);
+                       
+                       object default_value = 0;
+                       
+               
+                       foreach (string name in ordered_enums) {
+                               //
+                               // Have we already been defined, thanks to some cross-referencing ?
+                               // 
+                               if (member_to_value.Contains (name))
+                                       continue;
+                               
+                               Location loc = (Mono.CSharp.Location) member_to_location [name];
+
+                               if (this [name] != null) {
+                                       default_value = LookupEnumValue (ec, name, loc);
+
+                                       if (default_value == null)
+                                               return true;
+                               } else {
+                                       if (name == "value__"){
+                                               Report.Error (76, loc, "The name `value__' is reserved for enumerations");
+                                               return false;
+                                       }
+
+                                       EnumMember em = (EnumMember) defined_names [name];
+
+                                       em.DefineMember (TypeBuilder);
+                                       FieldBuilder fb = em.builder;
+                                       
+                                       if (default_value == null) {
+                                          Report.Error (543, loc, "Enumerator value for '" + name + "' is too large to " +
+                                                             "fit in its type");
+                                               return false;
+                                       }
+
+                                       bool fail;
+                                       default_value = TypeManager.ChangeType (default_value, UnderlyingType, out fail);
+                                       if (fail){
+                                               Error_ConstantValueCannotBeConverted (default_value, loc);
+                                               return false;
+                                       }
+
+                                       fb.SetConstant (default_value);
+                                       field_builders.Add (fb);
+                                       member_to_value [name] = default_value;
+                                       
+                                       if (!TypeManager.RegisterFieldValue (fb, default_value))
+                                               return false;
+                               }
+
+                               default_value = GetNextDefaultValue (default_value);
+                       }
+
+                       return true;
+               }
+
+               public override void Emit ()
+               {
+                       if (OptAttributes != null) {
+                               OptAttributes.Emit (ec, this);
+                       }
+
+                       foreach (EnumMember em in defined_names.Values) {
+                               em.Emit (ec);
+                       }
+
+                       base.Emit ();
+               }
+               
+               void VerifyClsName ()
+               {
+                       Hashtable ht = new Hashtable ();
+                       foreach (string name in ordered_enums) {
+                               string locase = name.ToLower (System.Globalization.CultureInfo.InvariantCulture);
+                               if (!ht.Contains (locase)) {
+                                       ht.Add (locase, defined_names [name]);
+                                       continue;
+                               }
+                               MemberCore conflict = (MemberCore)ht [locase];
+                               Report.SymbolRelatedToPreviousError (conflict);
+                               conflict = GetDefinition (name);
+                               Report.Error (3005, conflict.Location, "Identifier '{0}' differing only in case is not CLS-compliant", conflict.GetSignatureForError ());
+                       }
+               }
+
+               protected override bool VerifyClsCompliance (DeclSpace ds)
+               {
+                       if (!base.VerifyClsCompliance (ds))
+                               return false;
+
+                       VerifyClsName ();
+
+                       if (!AttributeTester.IsClsCompliant (UnderlyingType)) {
+                               Report.Error (3009, Location, "'{0}': base type '{1}' is not CLS-compliant", GetSignatureForError (), TypeManager.CSharpName (UnderlyingType));
+                       }
+
+                       return true;
+               }
+               
+               /// <summary>
+               /// Returns full enum name.
+               /// </summary>
+               string GetEnumeratorName (string valueName)
+               {
+                       return String.Concat (Name, ".", valueName);
+               }
+
+               //
+               // IMemberFinder
+               //
+               public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
+                                                       MemberFilter filter, object criteria)
+               {
+                       ArrayList members = new ArrayList ();
+
+                       if ((mt & MemberTypes.Field) != 0) {
+                               if (criteria is string){
+                                       if (member_to_value [criteria] == null && current_ec != null){
+                                               LookupEnumValue (current_ec, (string) criteria, Location.Null);
+                                       }
+                               }
+                               
+                               foreach (FieldBuilder fb in field_builders)
+                                       if (filter (fb, criteria) == true)
+                                               members.Add (fb);
+                       }
+
+                       return new MemberList (members);
+               }
+
+               public override MemberCache MemberCache {
+                       get {
+                               return null;
+                       }
+               }
+
+               public ArrayList ValueNames {
+                       get {
+                               return ordered_enums;
+                       }
+               }
+
+               // indexer
+               public Expression this [string name] {
+                       get {
+                               return ((EnumMember) defined_names [name]).Type;
+                       }
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Enum;
+                       }
+               }
+
+               protected override void VerifyObsoleteAttribute()
+               {
+                       // UnderlyingType is never obsolete
+               }
+
+               //
+               // Generates xml doc comments (if any), and if required,
+               // handle warning report.
+               //
+               internal override void GenerateDocComment (DeclSpace ds)
+               {
+                       DocUtil.GenerateEnumDocComment (this, ds);
+               }
+
+               //
+               //   Represents header string for documentation comment.
+               //
+               public override string DocCommentHeader {
+                       get { return "T:"; }
+               }
+       }
+}
diff --git a/mcs/bmcs/expression.cs b/mcs/bmcs/expression.cs
new file mode 100644 (file)
index 0000000..5bbf8ca
--- /dev/null
@@ -0,0 +1,9030 @@
+//
+// expression.cs: Expression representation for the IL tree.
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001, 2002, 2003 Ximian, Inc.
+// (C) 2003, 2004 Novell, Inc.
+//
+#define USE_OLD
+
+namespace Mono.CSharp {
+       using System;
+       using System.Collections;
+       using System.Reflection;
+       using System.Reflection.Emit;
+       using System.Text;
+
+       /// <summary>
+       ///   This is just a helper class, it is generated by Unary, UnaryMutator
+       ///   when an overloaded method has been found.  It just emits the code for a
+       ///   static call.
+       /// </summary>
+       public class StaticCallExpr : ExpressionStatement {
+               ArrayList args;
+               MethodInfo mi;
+
+               public StaticCallExpr (MethodInfo m, ArrayList a, Location l)
+               {
+                       mi = m;
+                       args = a;
+
+                       type = m.ReturnType;
+                       eclass = ExprClass.Value;
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       //
+                       // We are born fully resolved
+                       //
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       if (args != null) 
+                               Invocation.EmitArguments (ec, mi, args, false, null);
+
+                       ec.ig.Emit (OpCodes.Call, mi);
+                       return;
+               }
+               
+               static public StaticCallExpr MakeSimpleCall (EmitContext ec, MethodGroupExpr mg,
+                                                        Expression e, Location loc)
+               {
+                       ArrayList args;
+                       MethodBase method;
+                       
+                       args = new ArrayList (1);
+                       Argument a = new Argument (e, Argument.AType.Expression);
+
+                        // We need to resolve the arguments before sending them in !
+                        if (!a.Resolve (ec, loc))
+                                return null;
+
+                        args.Add (a);
+                       method = Invocation.OverloadResolve (
+                               ec, (MethodGroupExpr) mg, args, false, loc);
+
+                       if (method == null)
+                               return null;
+
+                       return new StaticCallExpr ((MethodInfo) method, args, loc);
+               }
+
+               public override void EmitStatement (EmitContext ec)
+               {
+                       Emit (ec);
+                       if (TypeManager.TypeToCoreType (type) != TypeManager.void_type)
+                               ec.ig.Emit (OpCodes.Pop);
+               }
+               
+               public MethodInfo Method {
+                       get { return mi; }
+               }
+       }
+
+       public class ParenthesizedExpression : Expression
+       {
+               public Expression Expr;
+
+               public ParenthesizedExpression (Expression expr, Location loc)
+               {
+                       this.Expr = expr;
+                       this.loc = loc;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       Expr = Expr.Resolve (ec);
+                       return Expr;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new Exception ("Should not happen");
+               }
+       }
+       
+       /// <summary>
+       ///   Unary expressions.  
+       /// </summary>
+       ///
+       /// <remarks>
+       ///   Unary implements unary expressions.   It derives from
+       ///   ExpressionStatement becuase the pre/post increment/decrement
+       ///   operators can be used in a statement context.
+       /// </remarks>
+       public class Unary : Expression {
+               public enum Operator : byte {
+                       UnaryPlus, UnaryNegation, LogicalNot, OnesComplement,
+                       Indirection, AddressOf,  TOP
+               }
+
+               public Operator Oper;
+               public Expression Expr;
+               
+               public Unary (Operator op, Expression expr, Location loc)
+               {
+                       this.Oper = op;
+                       this.Expr = expr;
+                       this.loc = loc;
+               }
+
+               /// <summary>
+               ///   Returns a stringified representation of the Operator
+               /// </summary>
+               static public string OperName (Operator oper)
+               {
+                       switch (oper){
+                       case Operator.UnaryPlus:
+                               return "+";
+                       case Operator.UnaryNegation:
+                               return "-";
+                       case Operator.LogicalNot:
+                               return "!";
+                       case Operator.OnesComplement:
+                               return "~";
+                       case Operator.AddressOf:
+                               return "&";
+                       case Operator.Indirection:
+                               return "*";
+                       }
+
+                       return oper.ToString ();
+               }
+
+               public static readonly string [] oper_names;
+
+               static Unary ()
+               {
+                       oper_names = new string [(int)Operator.TOP];
+
+                       oper_names [(int) Operator.UnaryPlus] = "op_UnaryPlus";
+                       oper_names [(int) Operator.UnaryNegation] = "op_UnaryNegation";
+                       oper_names [(int) Operator.LogicalNot] = "op_LogicalNot";
+                       oper_names [(int) Operator.OnesComplement] = "op_OnesComplement";
+                       oper_names [(int) Operator.Indirection] = "op_Indirection";
+                       oper_names [(int) Operator.AddressOf] = "op_AddressOf";
+               }
+
+               void Error23 (Type t)
+               {
+                       Error (
+                               23, "Operator " + OperName (Oper) +
+                               " cannot be applied to operand of type `" +
+                               TypeManager.CSharpName (t) + "'");
+               }
+
+               /// <remarks>
+               ///   The result has been already resolved:
+               ///
+               ///   FIXME: a minus constant -128 sbyte cant be turned into a
+               ///   constant byte.
+               /// </remarks>
+               static Expression TryReduceNegative (Constant expr)
+               {
+                       Expression e = null;
+
+                       if (expr is IntConstant)
+                               e = new IntConstant (-((IntConstant) expr).Value);
+                       else if (expr is UIntConstant){
+                               uint value = ((UIntConstant) expr).Value;
+
+                               if (value < 2147483649)
+                                       return new IntConstant (-(int)value);
+                               else
+                                       e = new LongConstant (-value);
+                       }
+                       else if (expr is LongConstant)
+                               e = new LongConstant (-((LongConstant) expr).Value);
+                       else if (expr is ULongConstant){
+                               ulong value = ((ULongConstant) expr).Value;
+
+                               if (value < 9223372036854775809)
+                                       return new LongConstant(-(long)value);
+                       }
+                       else if (expr is FloatConstant)
+                               e = new FloatConstant (-((FloatConstant) expr).Value);
+                       else if (expr is DoubleConstant)
+                               e = new DoubleConstant (-((DoubleConstant) expr).Value);
+                       else if (expr is DecimalConstant)
+                               e = new DecimalConstant (-((DecimalConstant) expr).Value);
+                       else if (expr is ShortConstant)
+                               e = new IntConstant (-((ShortConstant) expr).Value);
+                       else if (expr is UShortConstant)
+                               e = new IntConstant (-((UShortConstant) expr).Value);
+                       else if (expr is SByteConstant)
+                               e = new IntConstant (-((SByteConstant) expr).Value);
+                       else if (expr is ByteConstant)
+                               e = new IntConstant (-((ByteConstant) expr).Value);
+                       return e;
+               }
+
+               // <summary>
+               //   This routine will attempt to simplify the unary expression when the
+               //   argument is a constant.  The result is returned in `result' and the
+               //   function returns true or false depending on whether a reduction
+               //   was performed or not
+               // </summary>
+               bool Reduce (EmitContext ec, Constant e, out Expression result)
+               {
+                       Type expr_type = e.Type;
+                       
+                       switch (Oper){
+                       case Operator.UnaryPlus:
+                               result = e;
+                               return true;
+                               
+                       case Operator.UnaryNegation:
+                               result = TryReduceNegative (e);
+                               return result != null;
+                               
+                       case Operator.LogicalNot:
+                               if (expr_type != TypeManager.bool_type) {
+                                       result = null;
+                                       Error23 (expr_type);
+                                       return false;
+                               }
+                               
+                               BoolConstant b = (BoolConstant) e;
+                               result = new BoolConstant (!(b.Value));
+                               return true;
+                               
+                       case Operator.OnesComplement:
+                               if (!((expr_type == TypeManager.int32_type) ||
+                                     (expr_type == TypeManager.uint32_type) ||
+                                     (expr_type == TypeManager.int64_type) ||
+                                     (expr_type == TypeManager.uint64_type) ||
+                                     (expr_type.IsSubclassOf (TypeManager.enum_type)))){
+
+                                       result = null;
+                                       if (Convert.ImplicitConversionExists (ec, e, TypeManager.int32_type)){
+                                               result = new Cast (new TypeExpression (TypeManager.int32_type, loc), e, loc);
+                                               result = result.Resolve (ec);
+                                       } else if (Convert.ImplicitConversionExists (ec, e, TypeManager.uint32_type)){
+                                               result = new Cast (new TypeExpression (TypeManager.uint32_type, loc), e, loc);
+                                               result = result.Resolve (ec);
+                                       } else if (Convert.ImplicitConversionExists (ec, e, TypeManager.int64_type)){
+                                               result = new Cast (new TypeExpression (TypeManager.int64_type, loc), e, loc);
+                                               result = result.Resolve (ec);
+                                       } else if (Convert.ImplicitConversionExists (ec, e, TypeManager.uint64_type)){
+                                               result = new Cast (new TypeExpression (TypeManager.uint64_type, loc), e, loc);
+                                               result = result.Resolve (ec);
+                                       }
+
+                                       if (result == null || !(result is Constant)){
+                                               result = null;
+                                               Error23 (expr_type);
+                                               return false;
+                                       }
+
+                                       expr_type = result.Type;
+                                       e = (Constant) result;
+                               }
+
+                               if (e is EnumConstant){
+                                       EnumConstant enum_constant = (EnumConstant) e;
+                                       Expression reduced;
+                                       
+                                       if (Reduce (ec, enum_constant.Child, out reduced)){
+                                               result = new EnumConstant ((Constant) reduced, enum_constant.Type);
+                                               return true;
+                                       } else {
+                                               result = null;
+                                               return false;
+                                       }
+                               }
+
+                               if (expr_type == TypeManager.int32_type){
+                                       result = new IntConstant (~ ((IntConstant) e).Value);
+                               } else if (expr_type == TypeManager.uint32_type){
+                                       result = new UIntConstant (~ ((UIntConstant) e).Value);
+                               } else if (expr_type == TypeManager.int64_type){
+                                       result = new LongConstant (~ ((LongConstant) e).Value);
+                               } else if (expr_type == TypeManager.uint64_type){
+                                       result = new ULongConstant (~ ((ULongConstant) e).Value);
+                               } else {
+                                       result = null;
+                                       Error23 (expr_type);
+                                       return false;
+                               }
+                               return true;
+
+                       case Operator.AddressOf:
+                               result = this;
+                               return false;
+
+                       case Operator.Indirection:
+                               result = this;
+                               return false;
+                       }
+                       throw new Exception ("Can not constant fold: " + Oper.ToString());
+               }
+
+               Expression ResolveOperator (EmitContext ec)
+               {
+                       //
+                       // Step 1: Default operations on CLI native types.
+                       //
+
+                       // Attempt to use a constant folding operation.
+                       if (Expr is Constant){
+                               Expression result;
+                               
+                               if (Reduce (ec, (Constant) Expr, out result))
+                                       return result;
+                       }
+
+                       //
+                       // Step 2: Perform Operator Overload location
+                       //
+                       Type expr_type = Expr.Type;
+                       Expression mg;
+                       string op_name;
+                       
+                       op_name = oper_names [(int) Oper];
+
+                       mg = MemberLookup (ec, expr_type, op_name, MemberTypes.Method, AllBindingFlags, loc);
+                       
+                       if (mg != null) {
+                               Expression e = StaticCallExpr.MakeSimpleCall (
+                                       ec, (MethodGroupExpr) mg, Expr, loc);
+
+                               if (e == null){
+                                       Error23 (expr_type);
+                                       return null;
+                               }
+                               
+                               return e;
+                       }
+
+                       // Only perform numeric promotions on:
+                       // +, - 
+
+                       if (expr_type == null)
+                               return null;
+                       
+                       switch (Oper){
+                       case Operator.LogicalNot:
+                               if (expr_type != TypeManager.bool_type) {
+                                       Expr = ResolveBoolean (ec, Expr, loc);
+                                       if (Expr == null){
+                                               Error23 (expr_type);
+                                               return null;
+                                       }
+                               }
+                               
+                               type = TypeManager.bool_type;
+                               return this;
+
+                       case Operator.OnesComplement:
+                               if (!((expr_type == TypeManager.int32_type) ||
+                                     (expr_type == TypeManager.uint32_type) ||
+                                     (expr_type == TypeManager.int64_type) ||
+                                     (expr_type == TypeManager.uint64_type) ||
+                                     (expr_type.IsSubclassOf (TypeManager.enum_type)))){
+                                       Expression e;
+
+                                       e = Convert.ImplicitConversion (ec, Expr, TypeManager.int32_type, loc);
+                                       if (e != null){
+                                               type = TypeManager.int32_type;
+                                               return this;
+                                       }
+                                       e = Convert.ImplicitConversion (ec, Expr, TypeManager.uint32_type, loc);
+                                       if (e != null){
+                                               type = TypeManager.uint32_type;
+                                               return this;
+                                       }
+                                       e = Convert.ImplicitConversion (ec, Expr, TypeManager.int64_type, loc);
+                                       if (e != null){
+                                               type = TypeManager.int64_type;
+                                               return this;
+                                       }
+                                       e = Convert.ImplicitConversion (ec, Expr, TypeManager.uint64_type, loc);
+                                       if (e != null){
+                                               type = TypeManager.uint64_type;
+                                               return this;
+                                       }
+                                       Error23 (expr_type);
+                                       return null;
+                               }
+                               type = expr_type;
+                               return this;
+
+                       case Operator.AddressOf:
+                               if (Expr.eclass != ExprClass.Variable){
+                                       Error (211, "Cannot take the address of non-variables");
+                                       return null;
+                               }
+                               
+                               if (!ec.InUnsafe) {
+                                       UnsafeError (loc); 
+                                       return null;
+                               }
+                               
+                               if (!TypeManager.VerifyUnManaged (Expr.Type, loc)){
+                                       return null;
+                               }
+
+                               IVariable variable = Expr as IVariable;
+                               if (!ec.InFixedInitializer && ((variable == null) || !variable.VerifyFixed (false))) {
+                                       Error (212, "You can only take the address of an unfixed expression inside " +
+                                              "of a fixed statement initializer");
+                                       return null;
+                               }
+
+                               if (ec.InFixedInitializer && ((variable != null) && variable.VerifyFixed (false))) {
+                                       Error (213, "You can not fix an already fixed expression");
+                                       return null;
+                               }
+
+                               LocalVariableReference lr = Expr as LocalVariableReference;
+                               if (lr != null){
+                                       if (lr.local_info.IsCaptured){
+                                               AnonymousMethod.Error_AddressOfCapturedVar (lr.Name, loc);
+                                               return null;
+                                       }
+                                       lr.local_info.AddressTaken = true;
+                                       lr.local_info.Used = true;
+                               }
+
+                               // According to the specs, a variable is considered definitely assigned if you take
+                               // its address.
+                               if ((variable != null) && (variable.VariableInfo != null))
+                                       variable.VariableInfo.SetAssigned (ec);
+
+                               type = TypeManager.GetPointerType (Expr.Type);
+                               return this;
+
+                       case Operator.Indirection:
+                               if (!ec.InUnsafe){
+                                       UnsafeError (loc);
+                                       return null;
+                               }
+                               
+                               if (!expr_type.IsPointer){
+                                       Error (193, "The * or -> operator can only be applied to pointers");
+                                       return null;
+                               }
+                               
+                               //
+                               // We create an Indirection expression, because
+                               // it can implement the IMemoryLocation.
+                               // 
+                               return new Indirection (Expr, loc);
+                       
+                       case Operator.UnaryPlus:
+                               //
+                               // A plus in front of something is just a no-op, so return the child.
+                               //
+                               return Expr;
+
+                       case Operator.UnaryNegation:
+                               //
+                               // Deals with -literals
+                               // int     operator- (int x)
+                               // long    operator- (long x)
+                               // float   operator- (float f)
+                               // double  operator- (double d)
+                               // decimal operator- (decimal d)
+                               //
+                               Expression expr = null;
+
+                               //
+                               // transform - - expr into expr
+                               //
+                               if (Expr is Unary){
+                                       Unary unary = (Unary) Expr;
+                                       
+                                       if (unary.Oper == Operator.UnaryNegation)
+                                               return unary.Expr;
+                               }
+
+                               //
+                               // perform numeric promotions to int,
+                               // long, double.
+                               //
+                               //
+                               // The following is inneficient, because we call
+                               // ImplicitConversion too many times.
+                               //
+                               // It is also not clear if we should convert to Float
+                               // or Double initially.
+                               //
+                               if (expr_type == TypeManager.uint32_type){
+                                       //
+                                       // FIXME: handle exception to this rule that
+                                       // permits the int value -2147483648 (-2^31) to
+                                       // bt wrote as a decimal interger literal
+                                       //
+                                       type = TypeManager.int64_type;
+                                       Expr = Convert.ImplicitConversion (ec, Expr, type, loc);
+                                       return this;
+                               }
+
+                               if (expr_type == TypeManager.uint64_type){
+                                       //
+                                       // FIXME: Handle exception of `long value'
+                                       // -92233720368547758087 (-2^63) to be wrote as
+                                       // decimal integer literal.
+                                       //
+                                       Error23 (expr_type);
+                                       return null;
+                               }
+
+                               if (expr_type == TypeManager.float_type){
+                                       type = expr_type;
+                                       return this;
+                               }
+                               
+                               expr = Convert.ImplicitConversion (ec, Expr, TypeManager.int32_type, loc);
+                               if (expr != null){
+                                       Expr = expr;
+                                       type = expr.Type;
+                                       return this;
+                               } 
+
+                               expr = Convert.ImplicitConversion (ec, Expr, TypeManager.int64_type, loc);
+                               if (expr != null){
+                                       Expr = expr;
+                                       type = expr.Type;
+                                       return this;
+                               }
+
+                               expr = Convert.ImplicitConversion (ec, Expr, TypeManager.double_type, loc);
+                               if (expr != null){
+                                       Expr = expr;
+                                       type = expr.Type;
+                                       return this;
+                               }
+                               
+                               Error23 (expr_type);
+                               return null;
+                       }
+
+                       Error (187, "No such operator '" + OperName (Oper) + "' defined for type '" +
+                              TypeManager.CSharpName (expr_type) + "'");
+                       return null;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if (Oper == Operator.AddressOf)
+                               Expr = Expr.ResolveLValue (ec, new EmptyExpression ());
+                       else
+                               Expr = Expr.Resolve (ec);
+                       
+                       if (Expr == null)
+                               return null;
+
+                       eclass = ExprClass.Value;
+                       return ResolveOperator (ec);
+               }
+
+               public override Expression DoResolveLValue (EmitContext ec, Expression right)
+               {
+                       if (Oper == Operator.Indirection)
+                               return base.DoResolveLValue (ec, right);
+
+                       Error (131, "The left-hand side of an assignment must be a " +
+                              "variable, property or indexer");
+                       return null;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       switch (Oper) {
+                       case Operator.UnaryPlus:
+                               throw new Exception ("This should be caught by Resolve");
+                               
+                       case Operator.UnaryNegation:
+                               if (ec.CheckState) {
+                                       ig.Emit (OpCodes.Ldc_I4_0);
+                                       if (type == TypeManager.int64_type)
+                                               ig.Emit (OpCodes.Conv_U8);
+                                       Expr.Emit (ec);
+                                       ig.Emit (OpCodes.Sub_Ovf);
+                               } else {
+                               Expr.Emit (ec);
+                               ig.Emit (OpCodes.Neg);
+                               }
+                               
+                               break;
+                               
+                       case Operator.LogicalNot:
+                               Expr.Emit (ec);
+                               ig.Emit (OpCodes.Ldc_I4_0);
+                               ig.Emit (OpCodes.Ceq);
+                               break;
+                               
+                       case Operator.OnesComplement:
+                               Expr.Emit (ec);
+                               ig.Emit (OpCodes.Not);
+                               break;
+                               
+                       case Operator.AddressOf:
+                               ((IMemoryLocation)Expr).AddressOf (ec, AddressOp.LoadStore);
+                               break;
+                               
+                       default:
+                               throw new Exception ("This should not happen: Operator = "
+                                                    + Oper.ToString ());
+                       }
+               }
+
+               public override void EmitBranchable (EmitContext ec, Label target, bool onTrue)
+               {
+                       if (Oper == Operator.LogicalNot)
+                               Expr.EmitBranchable (ec, target, !onTrue);
+                       else
+                               base.EmitBranchable (ec, target, onTrue);
+               }
+
+               public override string ToString ()
+               {
+                       return "Unary (" + Oper + ", " + Expr + ")";
+               }
+               
+       }
+
+       //
+       // Unary operators are turned into Indirection expressions
+       // after semantic analysis (this is so we can take the address
+       // of an indirection).
+       //
+       public class Indirection : Expression, IMemoryLocation, IAssignMethod {
+               Expression expr;
+               LocalTemporary temporary;
+               bool prepared;
+               
+               public Indirection (Expression expr, Location l)
+               {
+                       this.expr = expr;
+                       this.type = TypeManager.GetElementType (expr.Type);
+                       eclass = ExprClass.Variable;
+                       loc = l;
+               }
+
+               void LoadExprValue (EmitContext ec)
+               {
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       if (!prepared)
+                               expr.Emit (ec);
+
+                       LoadFromPtr (ec.ig, Type);
+               }
+
+               public void Emit (EmitContext ec, bool leave_copy)
+               {
+                       Emit (ec);
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               temporary = new LocalTemporary (ec, expr.Type);
+                               temporary.Store (ec);
+                       }
+               }
+
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+               {
+                       prepared = prepare_for_load;
+
+                       expr.Emit (ec);
+
+                       if (prepare_for_load)
+                               ec.ig.Emit (OpCodes.Dup);
+
+                       source.Emit (ec);
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               temporary = new LocalTemporary (ec, expr.Type);
+                               temporary.Store (ec);
+                       }
+
+                       StoreFromPtr (ec.ig, type);
+
+                       if (temporary != null)
+                               temporary.Emit (ec);
+               }
+
+               public void AddressOf (EmitContext ec, AddressOp Mode)
+               {
+                       expr.Emit (ec);
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       //
+                       // Born fully resolved
+                       //
+                       return this;
+               }
+               
+               public override string ToString ()
+               {
+                       return "*(" + expr + ")";
+               }
+       }
+       
+       /// <summary>
+       ///   Unary Mutator expressions (pre and post ++ and --)
+       /// </summary>
+       ///
+       /// <remarks>
+       ///   UnaryMutator implements ++ and -- expressions.   It derives from
+       ///   ExpressionStatement becuase the pre/post increment/decrement
+       ///   operators can be used in a statement context.
+       ///
+       /// FIXME: Idea, we could split this up in two classes, one simpler
+       /// for the common case, and one with the extra fields for more complex
+       /// classes (indexers require temporary access;  overloaded require method)
+       ///
+       /// </remarks>
+       public class UnaryMutator : ExpressionStatement {
+               [Flags]
+               public enum Mode : byte {
+                       IsIncrement    = 0,
+                       IsDecrement    = 1,
+                       IsPre          = 0,
+                       IsPost         = 2,
+                       
+                       PreIncrement   = 0,
+                       PreDecrement   = IsDecrement,
+                       PostIncrement  = IsPost,
+                       PostDecrement  = IsPost | IsDecrement
+               }
+               
+               Mode mode;
+               bool is_expr = false;
+               bool recurse = false;
+               
+               Expression expr;
+
+               //
+               // This is expensive for the simplest case.
+               //
+               StaticCallExpr method;
+                       
+               public UnaryMutator (Mode m, Expression e, Location l)
+               {
+                       mode = m;
+                       loc = l;
+                       expr = e;
+               }
+
+               static string OperName (Mode mode)
+               {
+                       return (mode == Mode.PreIncrement || mode == Mode.PostIncrement) ?
+                               "++" : "--";
+               }
+               
+               void Error23 (Type t)
+               {
+                       Error (
+                               23, "Operator " + OperName (mode) + 
+                               " cannot be applied to operand of type `" +
+                               TypeManager.CSharpName (t) + "'");
+               }
+
+               /// <summary>
+               ///   Returns whether an object of type `t' can be incremented
+               ///   or decremented with add/sub (ie, basically whether we can
+               ///   use pre-post incr-decr operations on it, but it is not a
+               ///   System.Decimal, which we require operator overloading to catch)
+               /// </summary>
+               static bool IsIncrementableNumber (Type t)
+               {
+                       return (t == TypeManager.sbyte_type) ||
+                               (t == TypeManager.byte_type) ||
+                               (t == TypeManager.short_type) ||
+                               (t == TypeManager.ushort_type) ||
+                               (t == TypeManager.int32_type) ||
+                               (t == TypeManager.uint32_type) ||
+                               (t == TypeManager.int64_type) ||
+                               (t == TypeManager.uint64_type) ||
+                               (t == TypeManager.char_type) ||
+                               (t.IsSubclassOf (TypeManager.enum_type)) ||
+                               (t == TypeManager.float_type) ||
+                               (t == TypeManager.double_type) ||
+                               (t.IsPointer && t != TypeManager.void_ptr_type);
+               }
+
+               Expression ResolveOperator (EmitContext ec)
+               {
+                       Type expr_type = expr.Type;
+
+                       //
+                       // Step 1: Perform Operator Overload location
+                       //
+                       Expression mg;
+                       string op_name;
+                       
+                       if (mode == Mode.PreIncrement || mode == Mode.PostIncrement)
+                               op_name = "op_Increment";
+                       else 
+                               op_name = "op_Decrement";
+
+                       mg = MemberLookup (ec, expr_type, op_name, MemberTypes.Method, AllBindingFlags, loc);
+
+                       if (mg == null && expr_type.BaseType != null)
+                               mg = MemberLookup (ec, expr_type.BaseType, op_name,
+                                                  MemberTypes.Method, AllBindingFlags, loc);
+                       
+                       if (mg != null) {
+                               method = StaticCallExpr.MakeSimpleCall (
+                                       ec, (MethodGroupExpr) mg, expr, loc);
+
+                               type = method.Type;
+                               return this;
+                       }
+
+                       //
+                       // The operand of the prefix/postfix increment decrement operators
+                       // should be an expression that is classified as a variable,
+                       // a property access or an indexer access
+                       //
+                       type = expr_type;
+                       if (expr.eclass == ExprClass.Variable){
+                               LocalVariableReference var = expr as LocalVariableReference;
+                               if ((var != null) && var.IsReadOnly)
+                                       Error (1604, "cannot assign to `" + var.Name + "' because it is readonly");
+                               if (IsIncrementableNumber (expr_type) ||
+                                   expr_type == TypeManager.decimal_type){
+                                       return this;
+                               }
+                       } else if (expr.eclass == ExprClass.IndexerAccess){
+                               IndexerAccess ia = (IndexerAccess) expr;
+                               
+                               expr = ia.ResolveLValue (ec, this);
+                               if (expr == null)
+                                       return null;
+
+                               return this;
+                       } else if (expr.eclass == ExprClass.PropertyAccess){
+                               PropertyExpr pe = (PropertyExpr) expr;
+
+                               if (pe.VerifyAssignable ())
+                                       return this;
+
+                               return null;
+                       } else {
+                               expr.Error_UnexpectedKind ("variable, indexer or property access", loc);
+                               return null;
+                       }
+
+                       Error (187, "No such operator '" + OperName (mode) + "' defined for type '" +
+                              TypeManager.CSharpName (expr_type) + "'");
+                       return null;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       expr = expr.Resolve (ec);
+                       
+                       if (expr == null)
+                               return null;
+
+                       eclass = ExprClass.Value;
+                       return ResolveOperator (ec);
+               }
+
+               static int PtrTypeSize (Type t)
+               {
+                       return GetTypeSize (TypeManager.GetElementType (t));
+               }
+
+               //
+               // Loads the proper "1" into the stack based on the type, then it emits the
+               // opcode for the operation requested
+               //
+               void LoadOneAndEmitOp (EmitContext ec, Type t)
+               {
+                       //
+                       // Measure if getting the typecode and using that is more/less efficient
+                       // that comparing types.  t.GetTypeCode() is an internal call.
+                       //
+                       ILGenerator ig = ec.ig;
+                                                    
+                       if (t == TypeManager.uint64_type || t == TypeManager.int64_type)
+                               LongConstant.EmitLong (ig, 1);
+                       else if (t == TypeManager.double_type)
+                               ig.Emit (OpCodes.Ldc_R8, 1.0);
+                       else if (t == TypeManager.float_type)
+                               ig.Emit (OpCodes.Ldc_R4, 1.0F);
+                       else if (t.IsPointer){
+                               int n = PtrTypeSize (t);
+                               
+                               if (n == 0)
+                                       ig.Emit (OpCodes.Sizeof, t);
+                               else
+                                       IntConstant.EmitInt (ig, n);
+                       } else 
+                               ig.Emit (OpCodes.Ldc_I4_1);
+
+                       //
+                       // Now emit the operation
+                       //
+                       if (ec.CheckState){
+                               if (t == TypeManager.int32_type ||
+                                   t == TypeManager.int64_type){
+                                       if ((mode & Mode.IsDecrement) != 0)
+                                               ig.Emit (OpCodes.Sub_Ovf);
+                                       else
+                                               ig.Emit (OpCodes.Add_Ovf);
+                               } else if (t == TypeManager.uint32_type ||
+                                          t == TypeManager.uint64_type){
+                                       if ((mode & Mode.IsDecrement) != 0)
+                                               ig.Emit (OpCodes.Sub_Ovf_Un);
+                                       else
+                                               ig.Emit (OpCodes.Add_Ovf_Un);
+                               } else {
+                                       if ((mode & Mode.IsDecrement) != 0)
+                                               ig.Emit (OpCodes.Sub_Ovf);
+                                       else
+                                               ig.Emit (OpCodes.Add_Ovf);
+                               }
+                       } else {
+                               if ((mode & Mode.IsDecrement) != 0)
+                                       ig.Emit (OpCodes.Sub);
+                               else
+                                       ig.Emit (OpCodes.Add);
+                       }
+
+                       if (t == TypeManager.sbyte_type){
+                               if (ec.CheckState)
+                                       ig.Emit (OpCodes.Conv_Ovf_I1);
+                               else
+                                       ig.Emit (OpCodes.Conv_I1);
+                       } else if (t == TypeManager.byte_type){
+                               if (ec.CheckState)
+                                       ig.Emit (OpCodes.Conv_Ovf_U1);
+                               else
+                                       ig.Emit (OpCodes.Conv_U1);
+                       } else if (t == TypeManager.short_type){
+                               if (ec.CheckState)
+                                       ig.Emit (OpCodes.Conv_Ovf_I2);
+                               else
+                                       ig.Emit (OpCodes.Conv_I2);
+                       } else if (t == TypeManager.ushort_type || t == TypeManager.char_type){
+                               if (ec.CheckState)
+                                       ig.Emit (OpCodes.Conv_Ovf_U2);
+                               else
+                                       ig.Emit (OpCodes.Conv_U2);
+                       }
+                       
+               }
+               
+               void EmitCode (EmitContext ec, bool is_expr)
+               {
+                       recurse = true;
+                       this.is_expr = is_expr;
+                       ((IAssignMethod) expr).EmitAssign (ec, this, is_expr && (mode == Mode.PreIncrement || mode == Mode.PreDecrement), true);
+               }
+               
+
+               public override void Emit (EmitContext ec)
+               {
+                       //
+                       // We use recurse to allow ourselfs to be the source
+                       // of an assignment. This little hack prevents us from
+                       // having to allocate another expression
+                       //
+                       if (recurse) {
+                               ((IAssignMethod) expr).Emit (ec, is_expr && (mode == Mode.PostIncrement  || mode == Mode.PostDecrement));
+                               if (method == null)
+                                       LoadOneAndEmitOp (ec, expr.Type);
+                               else
+                                       ec.ig.Emit (OpCodes.Call, method.Method);
+                               recurse = false;
+                               return;
+                       }
+                       
+                       EmitCode (ec, true);
+               }
+               
+               public override void EmitStatement (EmitContext ec)
+               {
+                       EmitCode (ec, false);
+               }
+       }
+
+       /// <summary>
+       ///   Base class for the `Is' and `As' classes. 
+       /// </summary>
+       ///
+       /// <remarks>
+       ///   FIXME: Split this in two, and we get to save the `Operator' Oper
+       ///   size. 
+       /// </remarks>
+       public abstract class Probe : Expression {
+               public Expression ProbeType;
+               protected Expression expr;
+               protected Type probe_type;
+               
+               public Probe (Expression expr, Expression probe_type, Location l)
+               {
+                       ProbeType = probe_type;
+                       loc = l;
+                       this.expr = expr;
+               }
+
+               public Expression Expr {
+                       get {
+                               return expr;
+                       }
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       TypeExpr texpr = ProbeType.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return null;
+                       probe_type = texpr.Type;
+
+                       CheckObsoleteAttribute (probe_type);
+
+                       expr = expr.Resolve (ec);
+                       if (expr == null)
+                               return null;
+                       
+                       if (expr.Type.IsPointer) {
+                               Report.Error (244, loc, "\"is\" or \"as\" are not valid on pointer types");
+                               return null;
+                       }
+                       return this;
+               }
+       }
+
+       /// <summary>
+       ///   Implementation of the `is' operator.
+       /// </summary>
+       public class Is : Probe {
+               public Is (Expression expr, Expression probe_type, Location l)
+                       : base (expr, probe_type, l)
+               {
+               }
+
+               enum Action {
+                       AlwaysTrue, AlwaysNull, AlwaysFalse, LeaveOnStack, Probe
+               }
+
+               Action action;
+               
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       expr.Emit (ec);
+
+                       switch (action){
+                       case Action.AlwaysFalse:
+                               ig.Emit (OpCodes.Pop);
+                               IntConstant.EmitInt (ig, 0);
+                               return;
+                       case Action.AlwaysTrue:
+                               ig.Emit (OpCodes.Pop);
+                               IntConstant.EmitInt (ig, 1);
+                               return;
+                       case Action.LeaveOnStack:
+                               // the `e != null' rule.
+                               ig.Emit (OpCodes.Ldnull);
+                               ig.Emit (OpCodes.Ceq);
+                               ig.Emit (OpCodes.Ldc_I4_0);
+                               ig.Emit (OpCodes.Ceq);
+                               return;
+                       case Action.Probe:
+                               ig.Emit (OpCodes.Isinst, probe_type);
+                               ig.Emit (OpCodes.Ldnull);
+                               ig.Emit (OpCodes.Cgt_Un);
+                               return;
+                       }
+                       throw new Exception ("never reached");
+               }
+
+               public override void EmitBranchable (EmitContext ec, Label target, bool onTrue)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       switch (action){
+                       case Action.AlwaysFalse:
+                               if (! onTrue)
+                                       ig.Emit (OpCodes.Br, target);
+                               
+                               return;
+                       case Action.AlwaysTrue:
+                               if (onTrue)
+                                       ig.Emit (OpCodes.Br, target);
+                               
+                               return;
+                       case Action.LeaveOnStack:
+                               // the `e != null' rule.
+                               expr.Emit (ec);
+                               ig.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+                               return;
+                       case Action.Probe:
+                               expr.Emit (ec);
+                               ig.Emit (OpCodes.Isinst, probe_type);
+                               ig.Emit (onTrue ? OpCodes.Brtrue : OpCodes.Brfalse, target);
+                               return;
+                       }
+                       throw new Exception ("never reached");
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       Expression e = base.DoResolve (ec);
+
+                       if ((e == null) || (expr == null))
+                               return null;
+
+                       Type etype = expr.Type;
+                       bool warning_always_matches = false;
+                       bool warning_never_matches = false;
+
+                       type = TypeManager.bool_type;
+                       eclass = ExprClass.Value;
+
+                       //
+                       // First case, if at compile time, there is an implicit conversion
+                       // then e != null (objects) or true (value types)
+                       //
+                       e = Convert.ImplicitConversionStandard (ec, expr, probe_type, loc);
+                       if (e != null){
+                               expr = e;
+                               if (etype.IsValueType)
+                                       action = Action.AlwaysTrue;
+                               else
+                                       action = Action.LeaveOnStack;
+
+                               warning_always_matches = true;
+                       } else if (Convert.ExplicitReferenceConversionExists (etype, probe_type)){
+                               if (etype.IsGenericParameter)
+                                       expr = new BoxedCast (expr, etype);
+
+                               //
+                               // Second case: explicit reference convresion
+                               //
+                               if (expr is NullLiteral)
+                                       action = Action.AlwaysFalse;
+                               else
+                                       action = Action.Probe;
+                       } else {
+                               action = Action.AlwaysFalse;
+                               warning_never_matches = true;
+                       }
+                       
+                       if (warning_always_matches)
+                               Warning (183, "The given expression is always of the provided ('{0}') type", TypeManager.CSharpName (probe_type));
+                       else if (warning_never_matches){
+                               if (!(probe_type.IsInterface || expr.Type.IsInterface))
+                                       Warning (184, "The given expression is never of the provided ('{0}') type", TypeManager.CSharpName (probe_type));
+                       }
+
+                       return this;
+               }
+       }
+
+       /// <summary>
+       ///   Implementation of the `as' operator.
+       /// </summary>
+       public class As : Probe {
+               public As (Expression expr, Expression probe_type, Location l)
+                       : base (expr, probe_type, l)
+               {
+               }
+
+               bool do_isinst = false;
+               
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       expr.Emit (ec);
+
+                       if (do_isinst)
+                               ig.Emit (OpCodes.Isinst, probe_type);
+               }
+
+               static void Error_CannotConvertType (Type source, Type target, Location loc)
+               {
+                       Report.Error (
+                               39, loc, "as operator can not convert from `" +
+                               TypeManager.CSharpName (source) + "' to `" +
+                               TypeManager.CSharpName (target) + "'");
+               }
+               
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       Expression e = base.DoResolve (ec);
+
+                       if (e == null)
+                               return null;
+
+                       type = probe_type;
+                       eclass = ExprClass.Value;
+                       Type etype = expr.Type;
+
+                       if (TypeManager.IsValueType (probe_type)){
+                               Report.Error (77, loc, "The as operator should be used with a reference type only (" +
+                                             TypeManager.CSharpName (probe_type) + " is a value type)");
+                               return null;
+                       
+                       }
+                       
+                       e = Convert.ImplicitConversion (ec, expr, probe_type, loc);
+                       if (e != null){
+                               expr = e;
+                               do_isinst = false;
+                               return this;
+                       }
+
+                       if (Convert.ExplicitReferenceConversionExists (etype, probe_type)){
+                               if (etype.IsGenericParameter)
+                                       expr = new BoxedCast (expr, etype);
+
+                               do_isinst = true;
+                               return this;
+                       }
+
+                       Error_CannotConvertType (etype, probe_type, loc);
+                       return null;
+               }                               
+       }
+       
+       /// <summary>
+       ///   This represents a typecast in the source language.
+       ///
+       ///   FIXME: Cast expressions have an unusual set of parsing
+       ///   rules, we need to figure those out.
+       /// </summary>
+       public class Cast : Expression {
+               Expression target_type;
+               Expression expr;
+                       
+               public Cast (Expression cast_type, Expression expr, Location loc)
+               {
+                       this.target_type = cast_type;
+                       this.expr = expr;
+                       this.loc = loc;
+               }
+
+               public Expression TargetType {
+                       get {
+                               return target_type;
+                       }
+               }
+
+               public Expression Expr {
+                       get {
+                               return expr;
+                       }
+                       set {
+                               expr = value;
+                       }
+               }
+
+               bool CheckRange (EmitContext ec, long value, Type type, long min, long max)
+               {
+                       if (!ec.ConstantCheckState)
+                               return true;
+
+                       if ((value < min) || (value > max)) {
+                               Error (221, "Constant value `" + value + "' cannot be converted " +
+                                      "to a `" + TypeManager.CSharpName (type) + "' (use `unchecked' " +
+                                      "syntax to override)");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               bool CheckRange (EmitContext ec, ulong value, Type type, ulong max)
+               {
+                       if (!ec.ConstantCheckState)
+                               return true;
+
+                       if (value > max) {
+                               Error (221, "Constant value `" + value + "' cannot be converted " +
+                                      "to a `" + TypeManager.CSharpName (type) + "' (use `unchecked' " +
+                                      "syntax to override)");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               bool CheckUnsigned (EmitContext ec, long value, Type type)
+               {
+                       if (!ec.ConstantCheckState)
+                               return true;
+
+                       if (value < 0) {
+                               Error (221, "Constant value `" + value + "' cannot be converted " +
+                                      "to a `" + TypeManager.CSharpName (type) + "' (use `unchecked' " +
+                                      "syntax to override)");
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               /// <summary>
+               ///   Attempts to do a compile-time folding of a constant cast.
+               /// </summary>
+               Expression TryReduce (EmitContext ec, Type target_type)
+               {
+                       Expression real_expr = expr;
+                       if (real_expr is EnumConstant)
+                               real_expr = ((EnumConstant) real_expr).Child;
+                               
+                       if (real_expr is ByteConstant){
+                               byte v = ((ByteConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v);
+                               }
+                               if (target_type == TypeManager.short_type)
+                                       return new ShortConstant ((short) v);
+                               if (target_type == TypeManager.ushort_type)
+                                       return new UShortConstant ((ushort) v);
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v);
+                               if (target_type == TypeManager.uint32_type)
+                                       return new UIntConstant ((uint) v);
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v);
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v);
+                               if (target_type == TypeManager.char_type)
+                                       return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+                       if (real_expr is SByteConstant){
+                               sbyte v = ((SByteConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new ByteConstant ((byte) v);
+                               }
+                               if (target_type == TypeManager.short_type)
+                                       return new ShortConstant ((short) v);
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new UShortConstant ((ushort) v);
+                               } if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v);
+                               if (target_type == TypeManager.uint32_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new UIntConstant ((uint) v);
+                               } if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v);
+                               if (target_type == TypeManager.uint64_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new ULongConstant ((ulong) v);
+                               }
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new CharConstant ((char) v);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+                       if (real_expr is ShortConstant){
+                               short v = ((ShortConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v);
+                               }
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new UShortConstant ((ushort) v);
+                               }
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v);
+                               if (target_type == TypeManager.uint32_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new UIntConstant ((uint) v);
+                               }
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v);
+                               if (target_type == TypeManager.uint64_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new ULongConstant ((ulong) v);
+                               }
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+                       if (real_expr is UShortConstant){
+                               ushort v = ((UShortConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v);
+                               }
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v);
+                               if (target_type == TypeManager.uint32_type)
+                                       return new UIntConstant ((uint) v);
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v);
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+                       if (real_expr is IntConstant){
+                               int v = ((IntConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v);
+                               }
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt16.MinValue, UInt16.MaxValue))
+                                               return null;
+                                       return new UShortConstant ((ushort) v);
+                               }
+                               if (target_type == TypeManager.uint32_type) {
+                                       if (!CheckRange (ec, v, target_type, Int32.MinValue, Int32.MaxValue))
+                                               return null;
+                                       return new UIntConstant ((uint) v);
+                               }
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v);
+                               if (target_type == TypeManager.uint64_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new ULongConstant ((ulong) v);
+                               }
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+                       if (real_expr is UIntConstant){
+                               uint v = ((UIntConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v);
+                               }
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt16.MinValue, UInt16.MaxValue))
+                                               return null;
+                                       return new UShortConstant ((ushort) v);
+                               }
+                               if (target_type == TypeManager.int32_type) {
+                                       if (!CheckRange (ec, v, target_type, Int32.MinValue, Int32.MaxValue))
+                                               return null;
+                                       return new IntConstant ((int) v);
+                               }
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v);
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+                       if (real_expr is LongConstant){
+                               long v = ((LongConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v);
+                               }
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt16.MinValue, UInt16.MaxValue))
+                                               return null;
+                                       return new UShortConstant ((ushort) v);
+                               }
+                               if (target_type == TypeManager.int32_type) {
+                                       if (!CheckRange (ec, v, target_type, Int32.MinValue, Int32.MaxValue))
+                                               return null;
+                                       return new IntConstant ((int) v);
+                               }
+                               if (target_type == TypeManager.uint32_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt32.MinValue, UInt32.MaxValue))
+                                               return null;
+                                       return new UIntConstant ((uint) v);
+                               }
+                               if (target_type == TypeManager.uint64_type) {
+                                       if (!CheckUnsigned (ec, v, target_type))
+                                               return null;
+                                       return new ULongConstant ((ulong) v);
+                               }
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+                       if (real_expr is ULongConstant){
+                               ulong v = ((ULongConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, (ulong) SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, (ulong) Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v);
+                               }
+                               if (target_type == TypeManager.ushort_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt16.MaxValue))
+                                               return null;
+                                       return new UShortConstant ((ushort) v);
+                               }
+                               if (target_type == TypeManager.int32_type) {
+                                       if (!CheckRange (ec, v, target_type, Int32.MaxValue))
+                                               return null;
+                                       return new IntConstant ((int) v);
+                               }
+                               if (target_type == TypeManager.uint32_type) {
+                                       if (!CheckRange (ec, v, target_type, UInt32.MaxValue))
+                                               return null;
+                                       return new UIntConstant ((uint) v);
+                               }
+                               if (target_type == TypeManager.int64_type) {
+                                       if (!CheckRange (ec, v, target_type, (ulong) Int64.MaxValue))
+                                               return null;
+                                       return new LongConstant ((long) v);
+                               }
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+                       if (real_expr is FloatConstant){
+                               float v = ((FloatConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type)
+                                       return new ByteConstant ((byte) v);
+                               if (target_type == TypeManager.sbyte_type)
+                                       return new SByteConstant ((sbyte) v);
+                               if (target_type == TypeManager.short_type)
+                                       return new ShortConstant ((short) v);
+                               if (target_type == TypeManager.ushort_type)
+                                       return new UShortConstant ((ushort) v);
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v);
+                               if (target_type == TypeManager.uint32_type)
+                                       return new UIntConstant ((uint) v);
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v);
+                               if (target_type == TypeManager.char_type)
+                                       return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+                       if (real_expr is DoubleConstant){
+                               double v = ((DoubleConstant) real_expr).Value;
+       
+                               if (target_type == TypeManager.byte_type){
+                                       return new ByteConstant ((byte) v);
+                               } if (target_type == TypeManager.sbyte_type)
+                                       return new SByteConstant ((sbyte) v);
+                               if (target_type == TypeManager.short_type)
+                                       return new ShortConstant ((short) v);
+                               if (target_type == TypeManager.ushort_type)
+                                       return new UShortConstant ((ushort) v);
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v);
+                               if (target_type == TypeManager.uint32_type)
+                                       return new UIntConstant ((uint) v);
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v);
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v);
+                               if (target_type == TypeManager.char_type)
+                                       return new CharConstant ((char) v);
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+
+                       if (real_expr is CharConstant){
+                               char v = ((CharConstant) real_expr).Value;
+                               
+                               if (target_type == TypeManager.byte_type) {
+                                       if (!CheckRange (ec, v, target_type, Byte.MinValue, Byte.MaxValue))
+                                               return null;
+                                       return new ByteConstant ((byte) v);
+                               }
+                               if (target_type == TypeManager.sbyte_type) {
+                                       if (!CheckRange (ec, v, target_type, SByte.MinValue, SByte.MaxValue))
+                                               return null;
+                                       return new SByteConstant ((sbyte) v);
+                               }
+                               if (target_type == TypeManager.short_type) {
+                                       if (!CheckRange (ec, v, target_type, Int16.MinValue, Int16.MaxValue))
+                                               return null;
+                                       return new ShortConstant ((short) v);
+                               }
+                               if (target_type == TypeManager.int32_type)
+                                       return new IntConstant ((int) v);
+                               if (target_type == TypeManager.uint32_type)
+                                       return new UIntConstant ((uint) v);
+                               if (target_type == TypeManager.int64_type)
+                                       return new LongConstant ((long) v);
+                               if (target_type == TypeManager.uint64_type)
+                                       return new ULongConstant ((ulong) v);
+                               if (target_type == TypeManager.float_type)
+                                       return new FloatConstant ((float) v);
+                               if (target_type == TypeManager.double_type)
+                                       return new DoubleConstant ((double) v);
+                               if (target_type == TypeManager.char_type) {
+                                       if (!CheckRange (ec, v, target_type, Char.MinValue, Char.MaxValue))
+                                               return null;
+                                       return new CharConstant ((char) v);
+                               }
+                               if (target_type == TypeManager.decimal_type)
+                                       return new DecimalConstant ((decimal) v);
+                       }
+
+                       return null;
+               }
+               
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       expr = expr.Resolve (ec);
+                       if (expr == null)
+                               return null;
+
+                       TypeExpr target = target_type.ResolveAsTypeTerminal (ec);
+                       if (target == null)
+                               return null;
+                       
+                       type = target.Type;
+
+                       CheckObsoleteAttribute (type);
+
+                       if (type.IsAbstract && type.IsSealed) {
+                               Report.Error (716, loc, "Cannot convert to static type '{0}'", TypeManager.CSharpName (type));
+                               return null;
+                       }
+
+                       eclass = ExprClass.Value;
+
+                       if (expr is Constant){
+                               Expression e = TryReduce (ec, type);
+
+                               if (e != null)
+                                       return e;
+                       }
+
+                       if (type.IsPointer && !ec.InUnsafe) {
+                               UnsafeError (loc);
+                               return null;
+                       }
+                       expr = Convert.ExplicitConversion (ec, expr, type, loc);
+                       return expr;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       //
+                       // This one will never happen
+                       //
+                       throw new Exception ("Should not happen");
+               }
+       }
+
+       /// <summary>
+       ///   Binary operators
+       /// </summary>
+       public class Binary : Expression {
+               public enum Operator : byte {
+                       Multiply, Division, Modulus,
+                       Addition, Subtraction,
+                       LeftShift, RightShift,
+                       LessThan, GreaterThan, LessThanOrEqual, GreaterThanOrEqual, 
+                       Equality, Inequality,
+                       BitwiseAnd,
+                       ExclusiveOr,
+                       BitwiseOr,
+                       LogicalAnd,
+                       LogicalOr,
+                       TOP
+               }
+
+               Operator oper;
+               Expression left, right;
+
+               // This must be kept in sync with Operator!!!
+               public static readonly string [] oper_names;
+               
+               static Binary ()
+               {
+                       oper_names = new string [(int) Operator.TOP];
+
+                       oper_names [(int) Operator.Multiply] = "op_Multiply";
+                       oper_names [(int) Operator.Division] = "op_Division";
+                       oper_names [(int) Operator.Modulus] = "op_Modulus";
+                       oper_names [(int) Operator.Addition] = "op_Addition";
+                       oper_names [(int) Operator.Subtraction] = "op_Subtraction";
+                       oper_names [(int) Operator.LeftShift] = "op_LeftShift";
+                       oper_names [(int) Operator.RightShift] = "op_RightShift";
+                       oper_names [(int) Operator.LessThan] = "op_LessThan";
+                       oper_names [(int) Operator.GreaterThan] = "op_GreaterThan";
+                       oper_names [(int) Operator.LessThanOrEqual] = "op_LessThanOrEqual";
+                       oper_names [(int) Operator.GreaterThanOrEqual] = "op_GreaterThanOrEqual";
+                       oper_names [(int) Operator.Equality] = "op_Equality";
+                       oper_names [(int) Operator.Inequality] = "op_Inequality";
+                       oper_names [(int) Operator.BitwiseAnd] = "op_BitwiseAnd";
+                       oper_names [(int) Operator.BitwiseOr] = "op_BitwiseOr";
+                       oper_names [(int) Operator.ExclusiveOr] = "op_ExclusiveOr";
+                       oper_names [(int) Operator.LogicalOr] = "op_LogicalOr";
+                       oper_names [(int) Operator.LogicalAnd] = "op_LogicalAnd";
+               }
+
+               public Binary (Operator oper, Expression left, Expression right, Location loc)
+               {
+                       this.oper = oper;
+                       this.left = left;
+                       this.right = right;
+                       this.loc = loc;
+               }
+
+               public Operator Oper {
+                       get {
+                               return oper;
+                       }
+                       set {
+                               oper = value;
+                       }
+               }
+               
+               public Expression Left {
+                       get {
+                               return left;
+                       }
+                       set {
+                               left = value;
+                       }
+               }
+
+               public Expression Right {
+                       get {
+                               return right;
+                       }
+                       set {
+                               right = value;
+                       }
+               }
+
+
+               /// <summary>
+               ///   Returns a stringified representation of the Operator
+               /// </summary>
+               static string OperName (Operator oper)
+               {
+                       switch (oper){
+                       case Operator.Multiply:
+                               return "*";
+                       case Operator.Division:
+                               return "/";
+                       case Operator.Modulus:
+                               return "%";
+                       case Operator.Addition:
+                               return "+";
+                       case Operator.Subtraction:
+                               return "-";
+                       case Operator.LeftShift:
+                               return "<<";
+                       case Operator.RightShift:
+                               return ">>";
+                       case Operator.LessThan:
+                               return "<";
+                       case Operator.GreaterThan:
+                               return ">";
+                       case Operator.LessThanOrEqual:
+                               return "<=";
+                       case Operator.GreaterThanOrEqual:
+                               return ">=";
+                       case Operator.Equality:
+                               return "==";
+                       case Operator.Inequality:
+                               return "!=";
+                       case Operator.BitwiseAnd:
+                               return "&";
+                       case Operator.BitwiseOr:
+                               return "|";
+                       case Operator.ExclusiveOr:
+                               return "^";
+                       case Operator.LogicalOr:
+                               return "||";
+                       case Operator.LogicalAnd:
+                               return "&&";
+                       }
+
+                       return oper.ToString ();
+               }
+
+               public override string ToString ()
+               {
+                       return "operator " + OperName (oper) + "(" + left.ToString () + ", " +
+                               right.ToString () + ")";
+               }
+               
+               Expression ForceConversion (EmitContext ec, Expression expr, Type target_type)
+               {
+                       if (expr.Type == target_type)
+                               return expr;
+
+                       return Convert.ImplicitConversion (ec, expr, target_type, loc);
+               }
+
+               public static void Error_OperatorAmbiguous (Location loc, Operator oper, Type l, Type r)
+               {
+                       Report.Error (
+                               34, loc, "Operator `" + OperName (oper) 
+                               + "' is ambiguous on operands of type `"
+                               + TypeManager.CSharpName (l) + "' "
+                               + "and `" + TypeManager.CSharpName (r)
+                               + "'");
+               }
+
+               bool IsOfType (EmitContext ec, Type l, Type r, Type t, bool check_user_conversions)
+               {
+                       if ((l == t) || (r == t))
+                               return true;
+
+                       if (!check_user_conversions)
+                               return false;
+
+                       if (Convert.ImplicitUserConversionExists (ec, l, t))
+                               return true;
+                       else if (Convert.ImplicitUserConversionExists (ec, r, t))
+                               return true;
+                       else
+                               return false;
+               }
+
+               //
+               // Note that handling the case l == Decimal || r == Decimal
+               // is taken care of by the Step 1 Operator Overload resolution.
+               //
+               // If `check_user_conv' is true, we also check whether a user-defined conversion
+               // exists.  Note that we only need to do this if both arguments are of a user-defined
+               // type, otherwise ConvertImplict() already finds the user-defined conversion for us,
+               // so we don't explicitly check for performance reasons.
+               //
+               bool DoNumericPromotions (EmitContext ec, Type l, Type r, bool check_user_conv)
+               {
+                       if (IsOfType (ec, l, r, TypeManager.double_type, check_user_conv)){
+                               //
+                               // If either operand is of type double, the other operand is
+                               // conveted to type double.
+                               //
+                               if (r != TypeManager.double_type)
+                                       right = Convert.ImplicitConversion (ec, right, TypeManager.double_type, loc);
+                               if (l != TypeManager.double_type)
+                                       left = Convert.ImplicitConversion (ec, left, TypeManager.double_type, loc);
+                               
+                               type = TypeManager.double_type;
+                       } else if (IsOfType (ec, l, r, TypeManager.float_type, check_user_conv)){
+                               //
+                               // if either operand is of type float, the other operand is
+                               // converted to type float.
+                               //
+                               if (r != TypeManager.double_type)
+                                       right = Convert.ImplicitConversion (ec, right, TypeManager.float_type, loc);
+                               if (l != TypeManager.double_type)
+                                       left = Convert.ImplicitConversion (ec, left, TypeManager.float_type, loc);
+                               type = TypeManager.float_type;
+                       } else if (IsOfType (ec, l, r, TypeManager.uint64_type, check_user_conv)){
+                               Expression e;
+                               Type other;
+                               //
+                               // If either operand is of type ulong, the other operand is
+                               // converted to type ulong.  or an error ocurrs if the other
+                               // operand is of type sbyte, short, int or long
+                               //
+                               if (l == TypeManager.uint64_type){
+                                       if (r != TypeManager.uint64_type){
+                                               if (right is IntConstant){
+                                                       IntConstant ic = (IntConstant) right;
+                                                       
+                                                       e = Convert.TryImplicitIntConversion (l, ic);
+                                                       if (e != null)
+                                                               right = e;
+                                               } else if (right is LongConstant){
+                                                       long ll = ((LongConstant) right).Value;
+
+                                                       if (ll >= 0)
+                                                               right = new ULongConstant ((ulong) ll);
+                                               } else {
+                                                       e = Convert.ImplicitNumericConversion (ec, right, l, loc);
+                                                       if (e != null)
+                                                               right = e;
+                                               }
+                                       }
+                                       other = right.Type;
+                               } else {
+                                       if (left is IntConstant){
+                                               e = Convert.TryImplicitIntConversion (r, (IntConstant) left);
+                                               if (e != null)
+                                                       left = e;
+                                       } else if (left is LongConstant){
+                                               long ll = ((LongConstant) left).Value;
+                                               
+                                               if (ll > 0)
+                                                       left = new ULongConstant ((ulong) ll);
+                                       } else {
+                                               e = Convert.ImplicitNumericConversion (ec, left, r, loc);
+                                               if (e != null)
+                                                       left = e;
+                                       }
+                                       other = left.Type;
+                               }
+
+                               if ((other == TypeManager.sbyte_type) ||
+                                   (other == TypeManager.short_type) ||
+                                   (other == TypeManager.int32_type) ||
+                                   (other == TypeManager.int64_type))
+                                       Error_OperatorAmbiguous (loc, oper, l, r);
+                               else {
+                                       left = ForceConversion (ec, left, TypeManager.uint64_type);
+                                       right = ForceConversion (ec, right, TypeManager.uint64_type);
+                               }
+                               type = TypeManager.uint64_type;
+                       } else if (IsOfType (ec, l, r, TypeManager.int64_type, check_user_conv)){
+                               //
+                               // If either operand is of type long, the other operand is converted
+                               // to type long.
+                               //
+                               if (l != TypeManager.int64_type)
+                                       left = Convert.ImplicitConversion (ec, left, TypeManager.int64_type, loc);
+                               if (r != TypeManager.int64_type)
+                                       right = Convert.ImplicitConversion (ec, right, TypeManager.int64_type, loc);
+                               
+                               type = TypeManager.int64_type;
+                       } else if (IsOfType (ec, l, r, TypeManager.uint32_type, check_user_conv)){
+                               //
+                               // If either operand is of type uint, and the other
+                               // operand is of type sbyte, short or int, othe operands are
+                               // converted to type long (unless we have an int constant).
+                               //
+                               Type other = null;
+                               
+                               if (l == TypeManager.uint32_type){
+                                       if (right is IntConstant){
+                                               IntConstant ic = (IntConstant) right;
+                                               int val = ic.Value;
+                                               
+                                               if (val >= 0){
+                                                       right = new UIntConstant ((uint) val);
+                                                       type = l;
+                                                       
+                                                       return true;
+                                               }
+                                       }
+                                       other = r;
+                               } else if (r == TypeManager.uint32_type){
+                                       if (left is IntConstant){
+                                               IntConstant ic = (IntConstant) left;
+                                               int val = ic.Value;
+                                               
+                                               if (val >= 0){
+                                                       left = new UIntConstant ((uint) val);
+                                                       type = r;
+                                                       return true;
+                                               }
+                                       }
+                                       
+                                       other = l;
+                               }
+
+                               if ((other == TypeManager.sbyte_type) ||
+                                   (other == TypeManager.short_type) ||
+                                   (other == TypeManager.int32_type)){
+                                       left = ForceConversion (ec, left, TypeManager.int64_type);
+                                       right = ForceConversion (ec, right, TypeManager.int64_type);
+                                       type = TypeManager.int64_type;
+                               } else {
+                                       //
+                                       // if either operand is of type uint, the other
+                                       // operand is converd to type uint
+                                       //
+                                       left = ForceConversion (ec, left, TypeManager.uint32_type);
+                                       right = ForceConversion (ec, right, TypeManager.uint32_type);
+                                       type = TypeManager.uint32_type;
+                               } 
+                       } else if (l == TypeManager.decimal_type || r == TypeManager.decimal_type){
+                               if (l != TypeManager.decimal_type)
+                                       left = Convert.ImplicitConversion (ec, left, TypeManager.decimal_type, loc);
+
+                               if (r != TypeManager.decimal_type)
+                                       right = Convert.ImplicitConversion (ec, right, TypeManager.decimal_type, loc);
+                               type = TypeManager.decimal_type;
+                       } else {
+                               left = ForceConversion (ec, left, TypeManager.int32_type);
+                               right = ForceConversion (ec, right, TypeManager.int32_type);
+
+                               type = TypeManager.int32_type;
+                       }
+
+                       return (left != null) && (right != null);
+               }
+
+               static public void Error_OperatorCannotBeApplied (Location loc, string name, Type l, Type r)
+               {
+                       Report.Error (19, loc,
+                              "Operator " + name + " cannot be applied to operands of type `" +
+                              TypeManager.CSharpName (l) + "' and `" +
+                              TypeManager.CSharpName (r) + "'");
+               }
+               
+               void Error_OperatorCannotBeApplied ()
+               {
+                       Error_OperatorCannotBeApplied (loc, OperName (oper), left.Type, right.Type);
+               }
+
+               static bool is_unsigned (Type t)
+               {
+                       return (t == TypeManager.uint32_type || t == TypeManager.uint64_type ||
+                               t == TypeManager.short_type || t == TypeManager.byte_type);
+               }
+
+               static bool is_user_defined (Type t)
+               {
+                       if (t.IsSubclassOf (TypeManager.value_type) &&
+                           (!TypeManager.IsBuiltinType (t) || t == TypeManager.decimal_type))
+                               return true;
+                       else
+                               return false;
+               }
+
+               Expression Make32or64 (EmitContext ec, Expression e)
+               {
+                       Type t= e.Type;
+                       
+                       if (t == TypeManager.int32_type || t == TypeManager.uint32_type ||
+                           t == TypeManager.int64_type || t == TypeManager.uint64_type)
+                               return e;
+                       Expression ee = Convert.ImplicitConversion (ec, e, TypeManager.int32_type, loc);
+                       if (ee != null)
+                               return ee;
+                       ee = Convert.ImplicitConversion (ec, e, TypeManager.uint32_type, loc);
+                       if (ee != null)
+                               return ee;
+                       ee = Convert.ImplicitConversion (ec, e, TypeManager.int64_type, loc);
+                       if (ee != null)
+                               return ee;
+                       ee = Convert.ImplicitConversion (ec, e, TypeManager.uint64_type, loc);
+                       if (ee != null)
+                               return ee;
+                       return null;
+               }
+                                       
+               Expression CheckShiftArguments (EmitContext ec)
+               {
+                       Expression e;
+
+                       e = ForceConversion (ec, right, TypeManager.int32_type);
+                       if (e == null){
+                               Error_OperatorCannotBeApplied ();
+                               return null;
+                       }
+                       right = e;
+
+                       if (((e = Convert.ImplicitConversion (ec, left, TypeManager.int32_type, loc)) != null) ||
+                           ((e = Convert.ImplicitConversion (ec, left, TypeManager.uint32_type, loc)) != null) ||
+                           ((e = Convert.ImplicitConversion (ec, left, TypeManager.int64_type, loc)) != null) ||
+                           ((e = Convert.ImplicitConversion (ec, left, TypeManager.uint64_type, loc)) != null)){
+                               left = e;
+                               type = e.Type;
+
+                               if (type == TypeManager.int32_type || type == TypeManager.uint32_type){
+                                       right = new Binary (Binary.Operator.BitwiseAnd, right, new IntLiteral (31), loc);
+                                       right = right.DoResolve (ec);
+                               } else {
+                                       right = new Binary (Binary.Operator.BitwiseAnd, right, new IntLiteral (63), loc);
+                                       right = right.DoResolve (ec);
+                               }
+
+                               return this;
+                       }
+                       Error_OperatorCannotBeApplied ();
+                       return null;
+               }
+
+               Expression ResolveOperator (EmitContext ec)
+               {
+                       Type l = left.Type;
+                       Type r = right.Type;
+
+                       //
+                       // Special cases: string or type parameter comapred to null
+                       //
+                       if (oper == Operator.Equality || oper == Operator.Inequality){
+                               if ((!TypeManager.IsValueType (l) && r == TypeManager.null_type) ||
+                                   (!TypeManager.IsValueType (r) && l == TypeManager.null_type)) {
+                                       Type = TypeManager.bool_type;
+                                       
+                                       return this;
+                               }
+
+                               if (l.IsGenericParameter && (right is NullLiteral)) {
+                                       if (l.BaseType == TypeManager.value_type) {
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+
+                                       left = new BoxedCast (left);
+                                       Type = TypeManager.bool_type;
+                                       return this;
+                               }
+
+                               if (r.IsGenericParameter && (left is NullLiteral)) {
+                                       if (r.BaseType == TypeManager.value_type) {
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+
+                                       right = new BoxedCast (right);
+                                       Type = TypeManager.bool_type;
+                                       return this;
+                               }
+                               
+                               // IntPtr equality
+                               if (l == TypeManager.intptr_type && r == TypeManager.intptr_type) {
+                                       Type = TypeManager.bool_type;
+                                       
+                                       return this;
+                               }
+                       }
+
+                       //
+                       // Do not perform operator overload resolution when both sides are
+                       // built-in types
+                       //
+                       if (!(TypeManager.IsCLRType (l) && TypeManager.IsCLRType (r))){
+                               //
+                               // Step 1: Perform Operator Overload location
+                               //
+                               Expression left_expr, right_expr;
+                               
+                               string op = oper_names [(int) oper];
+                               
+                               MethodGroupExpr union;
+                               left_expr = MemberLookup (ec, l, op, MemberTypes.Method, AllBindingFlags, loc);
+                               if (r != l){
+                                       right_expr = MemberLookup (
+                                               ec, r, op, MemberTypes.Method, AllBindingFlags, loc);
+                                       union = Invocation.MakeUnionSet (left_expr, right_expr, loc);
+                               } else
+                                       union = (MethodGroupExpr) left_expr;
+                               
+                               if (union != null) {
+                                       ArrayList args = new ArrayList (2);
+                                       args.Add (new Argument (left, Argument.AType.Expression));
+                                       args.Add (new Argument (right, Argument.AType.Expression));
+                                       
+                                       MethodBase method = Invocation.OverloadResolve (
+                                               ec, union, args, true, Location.Null);
+
+                                       if (method != null) {
+                                               MethodInfo mi = (MethodInfo) method;
+                                               
+                                               return new BinaryMethod (mi.ReturnType, method, args);
+                                       }
+                               }
+                       }
+                       
+                       //
+                       // Step 0: String concatenation (because overloading will get this wrong)
+                       //
+                       if (oper == Operator.Addition){
+                               //
+                               // If any of the arguments is a string, cast to string
+                               //
+                               
+                               // Simple constant folding
+                               if (left is StringConstant && right is StringConstant)
+                                       return new StringConstant (((StringConstant) left).Value + ((StringConstant) right).Value);
+
+                               if (l == TypeManager.string_type || r == TypeManager.string_type) {
+
+                                       if (r == TypeManager.void_type || l == TypeManager.void_type) {
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+                                       
+                                       // try to fold it in on the left
+                                       if (left is StringConcat) {
+
+                                               //
+                                               // We have to test here for not-null, since we can be doubly-resolved
+                                               // take care of not appending twice
+                                               //
+                                               if (type == null){
+                                                       type = TypeManager.string_type;
+                                                       ((StringConcat) left).Append (ec, right);
+                                                       return left.Resolve (ec);
+                                               } else {
+                                                       return left;
+                                               }
+                                       }
+
+                                       // Otherwise, start a new concat expression
+                                       return new StringConcat (ec, loc, left, right).Resolve (ec);
+                               }
+
+                               //
+                               // Transform a + ( - b) into a - b
+                               //
+                               if (right is Unary){
+                                       Unary right_unary = (Unary) right;
+
+                                       if (right_unary.Oper == Unary.Operator.UnaryNegation){
+                                               oper = Operator.Subtraction;
+                                               right = right_unary.Expr;
+                                               r = right.Type;
+                                       }
+                               }
+                       }
+
+                       if (oper == Operator.Equality || oper == Operator.Inequality){
+                               if (l == TypeManager.bool_type || r == TypeManager.bool_type){
+                                       if (r != TypeManager.bool_type || l != TypeManager.bool_type){
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+                                       
+                                       type = TypeManager.bool_type;
+                                       return this;
+                               }
+
+                               //
+                               // operator != (object a, object b)
+                               // operator == (object a, object b)
+                               //
+                               // For this to be used, both arguments have to be reference-types.
+                               // Read the rationale on the spec (14.9.6)
+                               //
+                               // Also, if at compile time we know that the classes do not inherit
+                               // one from the other, then we catch the error there.
+                               //
+                               if (!(l.IsValueType || r.IsValueType)){
+                                       type = TypeManager.bool_type;
+
+                                       if (l == r)
+                                               return this;
+                                       
+                                       if (l.IsSubclassOf (r) || r.IsSubclassOf (l))
+                                               return this;
+
+                                       //
+                                       // Also, a standard conversion must exist from either one
+                                       //
+                                       if (!(Convert.ImplicitStandardConversionExists (ec, left, r) ||
+                                             Convert.ImplicitStandardConversionExists (ec, right, l))){
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+                                       //
+                                       // We are going to have to convert to an object to compare
+                                       //
+                                       if (l != TypeManager.object_type)
+                                               left = new EmptyCast (left, TypeManager.object_type);
+                                       if (r != TypeManager.object_type)
+                                               right = new EmptyCast (right, TypeManager.object_type);
+
+                                       //
+                                       // FIXME: CSC here catches errors cs254 and cs252
+                                       //
+                                       return this;
+                               }
+
+                               //
+                               // One of them is a valuetype, but the other one is not.
+                               //
+                               if (!l.IsValueType || !r.IsValueType) {
+                                       Error_OperatorCannotBeApplied ();
+                                       return null;
+                               }
+                       }
+
+                       // Only perform numeric promotions on:
+                       // +, -, *, /, %, &, |, ^, ==, !=, <, >, <=, >=
+                       //
+                       if (oper == Operator.Addition || oper == Operator.Subtraction) {
+                               if (TypeManager.IsDelegateType (l)){
+                                       if (((right.eclass == ExprClass.MethodGroup) ||
+                                            (r == TypeManager.anonymous_method_type))){
+                                               if ((RootContext.Version != LanguageVersion.ISO_1)){
+                                               Expression tmp = Convert.ImplicitConversionRequired (ec, right, l, loc);
+                                               if (tmp == null)
+                                                       return null;
+                                               right = tmp;
+                                               r = right.Type;
+                                       }
+                                       }
+                               
+                                       if (TypeManager.IsDelegateType (r)){
+                                       MethodInfo method;
+                                       ArrayList args = new ArrayList (2);
+                                       
+                                       args = new ArrayList (2);
+                                       args.Add (new Argument (left, Argument.AType.Expression));
+                                       args.Add (new Argument (right, Argument.AType.Expression));
+                                       
+                                       if (oper == Operator.Addition)
+                                               method = TypeManager.delegate_combine_delegate_delegate;
+                                       else
+                                               method = TypeManager.delegate_remove_delegate_delegate;
+
+                                       if (l != r) {
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+
+                                       return new BinaryDelegate (l, method, args);
+                               }
+                               }
+
+                               //
+                               // Pointer arithmetic:
+                               //
+                               // T* operator + (T* x, int y);
+                               // T* operator + (T* x, uint y);
+                               // T* operator + (T* x, long y);
+                               // T* operator + (T* x, ulong y);
+                               //
+                               // T* operator + (int y,   T* x);
+                               // T* operator + (uint y,  T *x);
+                               // T* operator + (long y,  T *x);
+                               // T* operator + (ulong y, T *x);
+                               //
+                               // T* operator - (T* x, int y);
+                               // T* operator - (T* x, uint y);
+                               // T* operator - (T* x, long y);
+                               // T* operator - (T* x, ulong y);
+                               //
+                               // long operator - (T* x, T *y)
+                               //
+                               if (l.IsPointer){
+                                       if (r.IsPointer && oper == Operator.Subtraction){
+                                               if (r == l)
+                                                       return new PointerArithmetic (
+                                                               false, left, right, TypeManager.int64_type,
+                                                               loc).Resolve (ec);
+                                       } else {
+                                               Expression t = Make32or64 (ec, right);
+                                               if (t != null)
+                                                       return new PointerArithmetic (oper == Operator.Addition, left, t, l, loc).Resolve (ec);
+                                       }
+                               } else if (r.IsPointer && oper == Operator.Addition){
+                                       Expression t = Make32or64 (ec, left);
+                                       if (t != null)
+                                               return new PointerArithmetic (true, right, t, r, loc).Resolve (ec);
+                               }
+                       }
+                       
+                       //
+                       // Enumeration operators
+                       //
+                       bool lie = TypeManager.IsEnumType (l);
+                       bool rie = TypeManager.IsEnumType (r);
+                       if (lie || rie){
+                               Expression temp;
+
+                               // U operator - (E e, E f)
+                               if (lie && rie){
+                                       if (oper == Operator.Subtraction){
+                                       if (l == r){
+                                               type = TypeManager.EnumToUnderlying (l);
+                                               return this;
+                                       } 
+                                       Error_OperatorCannotBeApplied ();
+                                       return null;
+                               }
+                               }
+                                       
+                               //
+                               // operator + (E e, U x)
+                               // operator - (E e, U x)
+                               //
+                               if (oper == Operator.Addition || oper == Operator.Subtraction){
+                                       Type enum_type = lie ? l : r;
+                                       Type other_type = lie ? r : l;
+                                       Type underlying_type = TypeManager.EnumToUnderlying (enum_type);
+                                       
+                                       if (underlying_type != other_type){
+                                               temp = Convert.ImplicitConversion (ec, lie ? right : left, underlying_type, loc);
+                                               if (temp != null){
+                                                       if (lie)
+                                                               right = temp;
+                                                       else
+                                                               left = temp;
+                                                       type = enum_type;
+                                                       return this;
+                                               }
+                                                       
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+
+                                       type = enum_type;
+                                       return this;
+                               }
+                               
+                               if (!rie){
+                                       temp = Convert.ImplicitConversion (ec, right, l, loc);
+                                       if (temp != null)
+                                               right = temp;
+                                       else {
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+                               } if (!lie){
+                                       temp = Convert.ImplicitConversion (ec, left, r, loc);
+                                       if (temp != null){
+                                               left = temp;
+                                               l = r;
+                                       } else {
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+                               }
+
+                               if (oper == Operator.Equality || oper == Operator.Inequality ||
+                                   oper == Operator.LessThanOrEqual || oper == Operator.LessThan ||
+                                   oper == Operator.GreaterThanOrEqual || oper == Operator.GreaterThan){
+                                       if (left.Type != right.Type){
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+                                       type = TypeManager.bool_type;
+                                       return this;
+                               }
+
+                               if (oper == Operator.BitwiseAnd ||
+                                   oper == Operator.BitwiseOr ||
+                                   oper == Operator.ExclusiveOr){
+                                       type = l;
+                                       return this;
+                               }
+                               Error_OperatorCannotBeApplied ();
+                               return null;
+                       }
+                       
+                       if (oper == Operator.LeftShift || oper == Operator.RightShift)
+                               return CheckShiftArguments (ec);
+
+                       if (oper == Operator.LogicalOr || oper == Operator.LogicalAnd){
+                               if (l == TypeManager.bool_type && r == TypeManager.bool_type) {
+                                       type = TypeManager.bool_type;
+                                       return this;
+                               }
+
+                               if (l != r) {
+                                       Error_OperatorCannotBeApplied ();
+                                       return null;
+                               }
+
+                               Expression e = new ConditionalLogicalOperator (
+                                       oper == Operator.LogicalAnd, left, right, l, loc);
+                               return e.Resolve (ec);
+                       } 
+
+                       //
+                       // operator & (bool x, bool y)
+                       // operator | (bool x, bool y)
+                       // operator ^ (bool x, bool y)
+                       //
+                       if (l == TypeManager.bool_type && r == TypeManager.bool_type){
+                               if (oper == Operator.BitwiseAnd ||
+                                   oper == Operator.BitwiseOr ||
+                                   oper == Operator.ExclusiveOr){
+                                       type = l;
+                                       return this;
+                               }
+                       }
+                       
+                       //
+                       // Pointer comparison
+                       //
+                       if (l.IsPointer && r.IsPointer){
+                               if (oper == Operator.Equality || oper == Operator.Inequality ||
+                                   oper == Operator.LessThan || oper == Operator.LessThanOrEqual ||
+                                   oper == Operator.GreaterThan || oper == Operator.GreaterThanOrEqual){
+                                       type = TypeManager.bool_type;
+                                       return this;
+                               }
+                       }
+                       
+                       //
+                       // This will leave left or right set to null if there is an error
+                       //
+                       bool check_user_conv = is_user_defined (l) && is_user_defined (r);
+                       DoNumericPromotions (ec, l, r, check_user_conv);
+                       if (left == null || right == null){
+                               Error_OperatorCannotBeApplied (loc, OperName (oper), l, r);
+                               return null;
+                       }
+
+                       //
+                       // reload our cached types if required
+                       //
+                       l = left.Type;
+                       r = right.Type;
+                       
+                       if (oper == Operator.BitwiseAnd ||
+                           oper == Operator.BitwiseOr ||
+                           oper == Operator.ExclusiveOr){
+                               if (l == r){
+                                       if (((l == TypeManager.int32_type) ||
+                                            (l == TypeManager.uint32_type) ||
+                                            (l == TypeManager.short_type) ||
+                                            (l == TypeManager.ushort_type) ||
+                                            (l == TypeManager.int64_type) ||
+                                            (l == TypeManager.uint64_type))){
+                                               type = l;
+                                       } else {
+                                               Error_OperatorCannotBeApplied ();
+                                               return null;
+                                       }
+                               } else {
+                                       Error_OperatorCannotBeApplied ();
+                                       return null;
+                               }
+                       }
+
+                       if (oper == Operator.Equality ||
+                           oper == Operator.Inequality ||
+                           oper == Operator.LessThanOrEqual ||
+                           oper == Operator.LessThan ||
+                           oper == Operator.GreaterThanOrEqual ||
+                           oper == Operator.GreaterThan){
+                               type = TypeManager.bool_type;
+                       }
+
+                       return this;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if ((oper == Operator.Subtraction) && (left is ParenthesizedExpression)) {
+                               left = ((ParenthesizedExpression) left).Expr;
+                               left = left.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.Type);
+                               if (left == null)
+                                       return null;
+
+                               if (left.eclass == ExprClass.Type) {
+                                       Error (75, "Casting a negative value needs to have the value in parentheses.");
+                                       return null;
+                               }
+                       } else
+                               left = left.Resolve (ec);
+
+                       if (left == null)
+                               return null;
+
+                       Constant lc = left as Constant;
+                       if (lc != null && lc.Type == TypeManager.bool_type && 
+                               ((oper == Operator.LogicalAnd && (bool)lc.GetValue () == false) ||
+                                (oper == Operator.LogicalOr && (bool)lc.GetValue () == true))) {
+
+                               // TODO: make a sence to resolve unreachable expression as we do for statement
+                               Report.Warning (429, 4, loc, "Unreachable expression code detected");
+                               return left;
+                       }
+
+                       right = right.Resolve (ec);
+                       if (right == null)
+                               return null;
+
+                       eclass = ExprClass.Value;
+
+                       Constant rc = right as Constant;
+                       if (rc != null & lc != null){
+                               Expression e = ConstantFold.BinaryFold (
+                                       ec, oper, lc, rc, loc);
+                                       if (e != null)
+                                               return e;
+                       }
+
+                       return ResolveOperator (ec);
+               }
+
+               /// <remarks>
+               ///   EmitBranchable is called from Statement.EmitBoolExpression in the
+               ///   context of a conditional bool expression.  This function will return
+               ///   false if it is was possible to use EmitBranchable, or true if it was.
+               ///
+               ///   The expression's code is generated, and we will generate a branch to `target'
+               ///   if the resulting expression value is equal to isTrue
+               /// </remarks>
+               public override void EmitBranchable (EmitContext ec, Label target, bool onTrue)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       //
+                       // This is more complicated than it looks, but its just to avoid
+                       // duplicated tests: basically, we allow ==, !=, >, <, >= and <=
+                       // but on top of that we want for == and != to use a special path
+                       // if we are comparing against null
+                       //
+                       if ((oper == Operator.Equality || oper == Operator.Inequality) && (left is Constant || right is Constant)) {
+                               bool my_on_true = oper == Operator.Inequality ? onTrue : !onTrue;
+
+                               //
+                               // put the constant on the rhs, for simplicity
+                               //
+                               if (left is Constant) {
+                                       Expression swap = right;
+                                       right = left;
+                                       left = swap;
+                               }
+                                       
+                               if (((Constant) right).IsZeroInteger) {
+                                       left.Emit (ec);
+                                       if (my_on_true)
+                                               ig.Emit (OpCodes.Brtrue, target);
+                                       else
+                                               ig.Emit (OpCodes.Brfalse, target);
+                                       
+                                       return;
+                               } else if (right is BoolConstant){
+                                       left.Emit (ec);
+                                       if (my_on_true != ((BoolConstant) right).Value)
+                                               ig.Emit (OpCodes.Brtrue, target);
+                                       else
+                                               ig.Emit (OpCodes.Brfalse, target);
+                                       
+                                       return;
+                               }
+
+                       } else if (oper == Operator.LogicalAnd) {
+
+                               if (onTrue) {
+                                               Label tests_end = ig.DefineLabel ();
+                                               
+                                       left.EmitBranchable (ec, tests_end, false);
+                                       right.EmitBranchable (ec, target, true);
+                                                       ig.MarkLabel (tests_end);
+                                       } else {
+                                       left.EmitBranchable (ec, target, false);
+                                       right.EmitBranchable (ec, target, false);
+                                       }
+
+                               return;
+                                                               
+                       } else if (oper == Operator.LogicalOr){
+                               if (onTrue) {
+                                       left.EmitBranchable (ec, target, true);
+                                       right.EmitBranchable (ec, target, true);
+                                               
+                                       } else {
+                                               Label tests_end = ig.DefineLabel ();
+                                       left.EmitBranchable (ec, tests_end, true);
+                                       right.EmitBranchable (ec, target, false);
+                                       ig.MarkLabel (tests_end);
+                               }
+                                               
+                               return;
+
+                       } else if (!(oper == Operator.LessThan        || oper == Operator.GreaterThan ||
+                                    oper == Operator.LessThanOrEqual || oper == Operator.GreaterThanOrEqual ||
+                                    oper == Operator.Equality        || oper == Operator.Inequality)) {
+                               base.EmitBranchable (ec, target, onTrue);
+                               return;
+                               }
+                               
+                       left.Emit (ec);
+                       right.Emit (ec);
+
+                       Type t = left.Type;
+                       bool isUnsigned = is_unsigned (t) || t == TypeManager.double_type || t == TypeManager.float_type;
+
+                       switch (oper){
+                       case Operator.Equality:
+                               if (onTrue)
+                                       ig.Emit (OpCodes.Beq, target);
+                               else
+                                       ig.Emit (OpCodes.Bne_Un, target);
+                               break;
+
+                       case Operator.Inequality:
+                               if (onTrue)
+                                       ig.Emit (OpCodes.Bne_Un, target);
+                               else
+                                       ig.Emit (OpCodes.Beq, target);
+                               break;
+
+                       case Operator.LessThan:
+                               if (onTrue)
+                                       if (isUnsigned)
+                                               ig.Emit (OpCodes.Blt_Un, target);
+                                       else
+                                               ig.Emit (OpCodes.Blt, target);
+                               else
+                                       if (isUnsigned)
+                                               ig.Emit (OpCodes.Bge_Un, target);
+                                       else
+                                               ig.Emit (OpCodes.Bge, target);
+                               break;
+
+                       case Operator.GreaterThan:
+                               if (onTrue)
+                                       if (isUnsigned)
+                                               ig.Emit (OpCodes.Bgt_Un, target);
+                                       else
+                                               ig.Emit (OpCodes.Bgt, target);
+                               else
+                                       if (isUnsigned)
+                                               ig.Emit (OpCodes.Ble_Un, target);
+                                       else
+                                               ig.Emit (OpCodes.Ble, target);
+                               break;
+
+                       case Operator.LessThanOrEqual:
+                               if (onTrue)
+                                       if (isUnsigned)
+                                               ig.Emit (OpCodes.Ble_Un, target);
+                                       else
+                                               ig.Emit (OpCodes.Ble, target);
+                               else
+                                       if (isUnsigned)
+                                               ig.Emit (OpCodes.Bgt_Un, target);
+                                       else
+                                               ig.Emit (OpCodes.Bgt, target);
+                               break;
+
+
+                       case Operator.GreaterThanOrEqual:
+                               if (onTrue)
+                                       if (isUnsigned)
+                                               ig.Emit (OpCodes.Bge_Un, target);
+                                       else
+                                               ig.Emit (OpCodes.Bge, target);
+                               else
+                                       if (isUnsigned)
+                                               ig.Emit (OpCodes.Blt_Un, target);
+                                       else
+                                               ig.Emit (OpCodes.Blt, target);
+                               break;
+                       default:
+                               Console.WriteLine (oper);
+                               throw new Exception ("what is THAT");
+                       }
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       Type l = left.Type;
+                       OpCode opcode;
+
+                       //
+                       // Handle short-circuit operators differently
+                       // than the rest
+                       //
+                       if (oper == Operator.LogicalAnd) {
+                               Label load_zero = ig.DefineLabel ();
+                               Label end = ig.DefineLabel ();
+
+                               left.EmitBranchable (ec, load_zero, false);
+                                               right.Emit (ec);
+                                               ig.Emit (OpCodes.Br, end);
+
+                               ig.MarkLabel (load_zero);
+                               ig.Emit (OpCodes.Ldc_I4_0);
+                               ig.MarkLabel (end);
+                               return;
+                       } else if (oper == Operator.LogicalOr) {
+                               Label load_one = ig.DefineLabel ();
+                               Label end = ig.DefineLabel ();
+                               
+                               left.EmitBranchable (ec, load_one, true);
+                                               right.Emit (ec);
+                                               ig.Emit (OpCodes.Br, end);
+
+                               ig.MarkLabel (load_one);
+                               ig.Emit (OpCodes.Ldc_I4_1);
+                               ig.MarkLabel (end);
+                               return;
+                       }
+
+                       left.Emit (ec);
+                       right.Emit (ec);
+
+                       bool isUnsigned = is_unsigned (left.Type);
+                       
+                       switch (oper){
+                       case Operator.Multiply:
+                               if (ec.CheckState){
+                                       if (l == TypeManager.int32_type || l == TypeManager.int64_type)
+                                               opcode = OpCodes.Mul_Ovf;
+                                       else if (isUnsigned)
+                                               opcode = OpCodes.Mul_Ovf_Un;
+                                       else
+                                               opcode = OpCodes.Mul;
+                               } else
+                                       opcode = OpCodes.Mul;
+
+                               break;
+
+                       case Operator.Division:
+                               if (isUnsigned)
+                                       opcode = OpCodes.Div_Un;
+                               else
+                                       opcode = OpCodes.Div;
+                               break;
+
+                       case Operator.Modulus:
+                               if (isUnsigned)
+                                       opcode = OpCodes.Rem_Un;
+                               else
+                                       opcode = OpCodes.Rem;
+                               break;
+
+                       case Operator.Addition:
+                               if (ec.CheckState){
+                                       if (l == TypeManager.int32_type || l == TypeManager.int64_type)
+                                               opcode = OpCodes.Add_Ovf;
+                                       else if (isUnsigned)
+                                               opcode = OpCodes.Add_Ovf_Un;
+                                       else
+                                               opcode = OpCodes.Add;
+                               } else
+                                       opcode = OpCodes.Add;
+                               break;
+
+                       case Operator.Subtraction:
+                               if (ec.CheckState){
+                                       if (l == TypeManager.int32_type || l == TypeManager.int64_type)
+                                               opcode = OpCodes.Sub_Ovf;
+                                       else if (isUnsigned)
+                                               opcode = OpCodes.Sub_Ovf_Un;
+                                       else
+                                               opcode = OpCodes.Sub;
+                               } else
+                                       opcode = OpCodes.Sub;
+                               break;
+
+                       case Operator.RightShift:
+                               if (isUnsigned)
+                                       opcode = OpCodes.Shr_Un;
+                               else
+                                       opcode = OpCodes.Shr;
+                               break;
+                               
+                       case Operator.LeftShift:
+                               opcode = OpCodes.Shl;
+                               break;
+
+                       case Operator.Equality:
+                               opcode = OpCodes.Ceq;
+                               break;
+
+                       case Operator.Inequality:
+                               ig.Emit (OpCodes.Ceq);
+                               ig.Emit (OpCodes.Ldc_I4_0);
+                               
+                               opcode = OpCodes.Ceq;
+                               break;
+
+                       case Operator.LessThan:
+                               if (isUnsigned)
+                                       opcode = OpCodes.Clt_Un;
+                               else
+                                       opcode = OpCodes.Clt;
+                               break;
+
+                       case Operator.GreaterThan:
+                               if (isUnsigned)
+                                       opcode = OpCodes.Cgt_Un;
+                               else
+                                       opcode = OpCodes.Cgt;
+                               break;
+
+                       case Operator.LessThanOrEqual:
+                               Type lt = left.Type;
+                               
+                               if (isUnsigned || (lt == TypeManager.double_type || lt == TypeManager.float_type))
+                                       ig.Emit (OpCodes.Cgt_Un);
+                               else
+                                       ig.Emit (OpCodes.Cgt);
+                               ig.Emit (OpCodes.Ldc_I4_0);
+                               
+                               opcode = OpCodes.Ceq;
+                               break;
+
+                       case Operator.GreaterThanOrEqual:
+                               Type le = left.Type;
+                               
+                               if (isUnsigned || (le == TypeManager.double_type || le == TypeManager.float_type))
+                                       ig.Emit (OpCodes.Clt_Un);
+                               else
+                                       ig.Emit (OpCodes.Clt);
+                               
+                               ig.Emit (OpCodes.Ldc_I4_0);
+                               
+                               opcode = OpCodes.Ceq;
+                               break;
+
+                       case Operator.BitwiseOr:
+                               opcode = OpCodes.Or;
+                               break;
+
+                       case Operator.BitwiseAnd:
+                               opcode = OpCodes.And;
+                               break;
+
+                       case Operator.ExclusiveOr:
+                               opcode = OpCodes.Xor;
+                               break;
+
+                       default:
+                               throw new Exception ("This should not happen: Operator = "
+                                                    + oper.ToString ());
+                       }
+
+                       ig.Emit (opcode);
+               }
+       }
+
+       //
+       // Object created by Binary when the binary operator uses an method instead of being
+       // a binary operation that maps to a CIL binary operation.
+       //
+       public class BinaryMethod : Expression {
+               public MethodBase method;
+               public ArrayList  Arguments;
+               
+               public BinaryMethod (Type t, MethodBase m, ArrayList args)
+               {
+                       method = m;
+                       Arguments = args;
+                       type = t;
+                       eclass = ExprClass.Value;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       if (Arguments != null) 
+                               Invocation.EmitArguments (ec, method, Arguments, false, null);
+                       
+                       if (method is MethodInfo)
+                               ig.Emit (OpCodes.Call, (MethodInfo) method);
+                       else
+                               ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+               }
+       }
+
+       //
+       // Represents the operation a + b [+ c [+ d [+ ...]]], where a is a string
+       // b, c, d... may be strings or objects.
+       //
+       public class StringConcat : Expression {
+               ArrayList operands;
+               bool invalid = false;
+               bool emit_conv_done = false;
+               //
+               // Are we also concating objects?
+               //
+               bool is_strings_only = true;
+               
+               public StringConcat (EmitContext ec, Location loc, Expression left, Expression right)
+               {
+                       this.loc = loc;
+                       type = TypeManager.string_type;
+                       eclass = ExprClass.Value;
+               
+                       operands = new ArrayList (2);
+                       Append (ec, left);
+                       Append (ec, right);
+               }
+               
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if (invalid)
+                               return null;
+                       
+                       return this;
+               }
+               
+               public void Append (EmitContext ec, Expression operand)
+               {
+                       //
+                       // Constant folding
+                       //
+                       if (operand is StringConstant && operands.Count != 0) {
+                               StringConstant last_operand = operands [operands.Count - 1] as StringConstant;
+                               if (last_operand != null) {
+                                       operands [operands.Count - 1] = new StringConstant (last_operand.Value + ((StringConstant) operand).Value);
+                                       return;
+                               }
+                       }
+                       
+                       //
+                       // Conversion to object
+                       //
+                       if (operand.Type != TypeManager.string_type) {
+                               Expression no = Convert.ImplicitConversion (ec, operand, TypeManager.object_type, loc);
+                               
+                               if (no == null) {
+                                       Binary.Error_OperatorCannotBeApplied (loc, "+", TypeManager.string_type, operand.Type);
+                                       invalid = true;
+                               }
+                               operand = no;
+                       }
+                       
+                       operands.Add (operand);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       MethodInfo concat_method = null;
+                       
+                       //
+                       // Do conversion to arguments; check for strings only
+                       //
+                       
+                       // This can get called multiple times, so we have to deal with that.
+                       if (!emit_conv_done) {
+                               emit_conv_done = true;
+                       for (int i = 0; i < operands.Count; i ++) {
+                               Expression e = (Expression) operands [i];
+                               is_strings_only &= e.Type == TypeManager.string_type;
+                       }
+                       
+                       for (int i = 0; i < operands.Count; i ++) {
+                               Expression e = (Expression) operands [i];
+                               
+                               if (! is_strings_only && e.Type == TypeManager.string_type) {
+                                       // need to make sure this is an object, because the EmitParams
+                                       // method might look at the type of this expression, see it is a
+                                       // string and emit a string [] when we want an object [];
+                                       
+                                               e = new EmptyCast (e, TypeManager.object_type);
+                               }
+                               operands [i] = new Argument (e, Argument.AType.Expression);
+                       }
+                       }
+                       
+                       //
+                       // Find the right method
+                       //
+                       switch (operands.Count) {
+                       case 1:
+                               //
+                               // This should not be possible, because simple constant folding
+                               // is taken care of in the Binary code.
+                               //
+                               throw new Exception ("how did you get here?");
+                       
+                       case 2:
+                               concat_method = is_strings_only ? 
+                                       TypeManager.string_concat_string_string :
+                                       TypeManager.string_concat_object_object ;
+                               break;
+                       case 3:
+                               concat_method = is_strings_only ? 
+                                       TypeManager.string_concat_string_string_string :
+                                       TypeManager.string_concat_object_object_object ;
+                               break;
+                       case 4:
+                               //
+                               // There is not a 4 param overlaod for object (the one that there is
+                               // is actually a varargs methods, and is only in corlib because it was
+                               // introduced there before.).
+                               //
+                               if (!is_strings_only)
+                                       goto default;
+                               
+                               concat_method = TypeManager.string_concat_string_string_string_string;
+                               break;
+                       default:
+                               concat_method = is_strings_only ? 
+                                       TypeManager.string_concat_string_dot_dot_dot :
+                                       TypeManager.string_concat_object_dot_dot_dot ;
+                               break;
+                       }
+                       
+                       Invocation.EmitArguments (ec, concat_method, operands, false, null);
+                       ec.ig.Emit (OpCodes.Call, concat_method);
+               }
+       }
+
+       //
+       // Object created with +/= on delegates
+       //
+       public class BinaryDelegate : Expression {
+               MethodInfo method;
+               ArrayList  args;
+
+               public BinaryDelegate (Type t, MethodInfo mi, ArrayList args)
+               {
+                       method = mi;
+                       this.args = args;
+                       type = t;
+                       eclass = ExprClass.Value;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       Invocation.EmitArguments (ec, method, args, false, null);
+                       
+                       ig.Emit (OpCodes.Call, (MethodInfo) method);
+                       ig.Emit (OpCodes.Castclass, type);
+               }
+
+               public Expression Right {
+                       get {
+                               Argument arg = (Argument) args [1];
+                               return arg.Expr;
+                       }
+               }
+
+               public bool IsAddition {
+                       get {
+                               return method == TypeManager.delegate_combine_delegate_delegate;
+                       }
+               }
+       }
+       
+       //
+       // User-defined conditional logical operator
+       public class ConditionalLogicalOperator : Expression {
+               Expression left, right;
+               bool is_and;
+
+               public ConditionalLogicalOperator (bool is_and, Expression left, Expression right, Type t, Location loc)
+               {
+                       type = t;
+                       eclass = ExprClass.Value;
+                       this.loc = loc;
+                       this.left = left;
+                       this.right = right;
+                       this.is_and = is_and;
+               }
+
+               protected void Error19 ()
+               {
+                       Binary.Error_OperatorCannotBeApplied (loc, is_and ? "&&" : "||", type, type);
+               }
+
+               protected void Error218 ()
+               {
+                       Error (218, "The type ('" + TypeManager.CSharpName (type) + "') must contain " +
+                              "declarations of operator true and operator false");
+               }
+
+               Expression op_true, op_false, op;
+               LocalTemporary left_temp;
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       MethodInfo method;
+                       Expression operator_group;
+
+                       operator_group = MethodLookup (ec, type, is_and ? "op_BitwiseAnd" : "op_BitwiseOr", loc);
+                       if (operator_group == null) {
+                               Error19 ();
+                               return null;
+                       }
+
+                       left_temp = new LocalTemporary (ec, type);
+
+                       ArrayList arguments = new ArrayList ();
+                       arguments.Add (new Argument (left_temp, Argument.AType.Expression));
+                       arguments.Add (new Argument (right, Argument.AType.Expression));
+                       method = Invocation.OverloadResolve (
+                               ec, (MethodGroupExpr) operator_group, arguments, false, loc)
+                               as MethodInfo;
+                       if ((method == null) || (method.ReturnType != type)) {
+                               Error19 ();
+                               return null;
+                       }
+
+                       op = new StaticCallExpr (method, arguments, loc);
+
+                       op_true = GetOperatorTrue (ec, left_temp, loc);
+                       op_false = GetOperatorFalse (ec, left_temp, loc);
+                       if ((op_true == null) || (op_false == null)) {
+                               Error218 ();
+                               return null;
+                       }
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       Label false_target = ig.DefineLabel ();
+                       Label end_target = ig.DefineLabel ();
+
+                       left.Emit (ec);
+                       left_temp.Store (ec);
+
+                       (is_and ? op_false : op_true).EmitBranchable (ec, false_target, false);
+                       left_temp.Emit (ec);
+                       ig.Emit (OpCodes.Br, end_target);
+                       ig.MarkLabel (false_target);
+                       op.Emit (ec);
+                       ig.MarkLabel (end_target);
+               }
+       }
+
+       public class PointerArithmetic : Expression {
+               Expression left, right;
+               bool is_add;
+
+               //
+               // We assume that `l' is always a pointer
+               //
+               public PointerArithmetic (bool is_addition, Expression l, Expression r, Type t, Location loc)
+               {
+                       type = t;
+                       this.loc = loc;
+                       left = l;
+                       right = r;
+                       is_add = is_addition;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       eclass = ExprClass.Variable;
+                       
+                       if (left.Type == TypeManager.void_ptr_type) {
+                               Error (242, "The operation in question is undefined on void pointers");
+                               return null;
+                       }
+                       
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       Type op_type = left.Type;
+                       ILGenerator ig = ec.ig;
+                       Type element = TypeManager.GetElementType (op_type);
+                       int size = GetTypeSize (element);
+                       Type rtype = right.Type;
+                       
+                       if (rtype.IsPointer){
+                               //
+                               // handle (pointer - pointer)
+                               //
+                               left.Emit (ec);
+                               right.Emit (ec);
+                               ig.Emit (OpCodes.Sub);
+
+                               if (size != 1){
+                                       if (size == 0)
+                                               ig.Emit (OpCodes.Sizeof, element);
+                                       else 
+                                               IntLiteral.EmitInt (ig, size);
+                                       ig.Emit (OpCodes.Div);
+                               }
+                               ig.Emit (OpCodes.Conv_I8);
+                       } else {
+                               //
+                               // handle + and - on (pointer op int)
+                               //
+                               left.Emit (ec);
+                               ig.Emit (OpCodes.Conv_I);
+                               right.Emit (ec);
+                               if (size != 1){
+                                       if (size == 0)
+                                               ig.Emit (OpCodes.Sizeof, element);
+                                       else 
+                                               IntLiteral.EmitInt (ig, size);
+                                       if (rtype == TypeManager.int64_type)
+                                               ig.Emit (OpCodes.Conv_I8);
+                                       else if (rtype == TypeManager.uint64_type)
+                                               ig.Emit (OpCodes.Conv_U8);
+                                       ig.Emit (OpCodes.Mul);
+                               }
+                               
+                               if (rtype == TypeManager.int64_type || rtype == TypeManager.uint64_type)
+                                       ig.Emit (OpCodes.Conv_I);
+                               
+                               if (is_add)
+                                       ig.Emit (OpCodes.Add);
+                               else
+                                       ig.Emit (OpCodes.Sub);
+                       }
+               }
+       }
+       
+       /// <summary>
+       ///   Implements the ternary conditional operator (?:)
+       /// </summary>
+       public class Conditional : Expression {
+               Expression expr, trueExpr, falseExpr;
+               
+               public Conditional (Expression expr, Expression trueExpr, Expression falseExpr, Location l)
+               {
+                       this.expr = expr;
+                       this.trueExpr = trueExpr;
+                       this.falseExpr = falseExpr;
+                       this.loc = l;
+               }
+
+               public Expression Expr {
+                       get {
+                               return expr;
+                       }
+               }
+
+               public Expression TrueExpr {
+                       get {
+                               return trueExpr;
+                       }
+               }
+
+               public Expression FalseExpr {
+                       get {
+                               return falseExpr;
+                       }
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       expr = expr.Resolve (ec);
+
+                       if (expr == null)
+                               return null;
+                       
+                       if (expr.Type != TypeManager.bool_type){
+                               expr = Expression.ResolveBoolean (
+                                       ec, expr, loc);
+                               
+                               if (expr == null)
+                                       return null;
+                       }
+                       
+                       trueExpr = trueExpr.Resolve (ec);
+                       falseExpr = falseExpr.Resolve (ec);
+
+                       if (trueExpr == null || falseExpr == null)
+                               return null;
+
+                       eclass = ExprClass.Value;
+                       if (trueExpr.Type == falseExpr.Type)
+                               type = trueExpr.Type;
+                       else {
+                               Expression conv;
+                               Type true_type = trueExpr.Type;
+                               Type false_type = falseExpr.Type;
+
+                               //
+                               // First, if an implicit conversion exists from trueExpr
+                               // to falseExpr, then the result type is of type falseExpr.Type
+                               //
+                               conv = Convert.ImplicitConversion (ec, trueExpr, false_type, loc);
+                               if (conv != null){
+                                       //
+                                       // Check if both can convert implicitl to each other's type
+                                       //
+                                       if (Convert.ImplicitConversion (ec, falseExpr, true_type, loc) != null){
+                                               Error (172,
+                                                      "Can not compute type of conditional expression " +
+                                                      "as `" + TypeManager.CSharpName (trueExpr.Type) +
+                                                      "' and `" + TypeManager.CSharpName (falseExpr.Type) +
+                                                      "' convert implicitly to each other");
+                                               return null;
+                                       }
+                                       type = false_type;
+                                       trueExpr = conv;
+                               } else if ((conv = Convert.ImplicitConversion(ec, falseExpr, true_type,loc))!= null){
+                                       type = true_type;
+                                       falseExpr = conv;
+                               } else {
+                                       Error (173, "The type of the conditional expression can " +
+                                              "not be computed because there is no implicit conversion" +
+                                              " from `" + TypeManager.CSharpName (trueExpr.Type) + "'" +
+                                              " and `" + TypeManager.CSharpName (falseExpr.Type) + "'");
+                                       return null;
+                               }
+                       }
+
+                       if (expr is BoolConstant){
+                               BoolConstant bc = (BoolConstant) expr;
+
+                               if (bc.Value)
+                                       return trueExpr;
+                               else
+                                       return falseExpr;
+                       }
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       Label false_target = ig.DefineLabel ();
+                       Label end_target = ig.DefineLabel ();
+
+                       expr.EmitBranchable (ec, false_target, false);
+                       trueExpr.Emit (ec);
+                       ig.Emit (OpCodes.Br, end_target);
+                       ig.MarkLabel (false_target);
+                       falseExpr.Emit (ec);
+                       ig.MarkLabel (end_target);
+               }
+
+       }
+
+       /// <summary>
+       ///   Local variables
+       /// </summary>
+       public class LocalVariableReference : Expression, IAssignMethod, IMemoryLocation, IVariable {
+               public readonly string Name;
+               public readonly Block Block;
+               public LocalInfo local_info;
+               bool is_readonly;
+               bool prepared;
+               LocalTemporary temp;
+               
+               public LocalVariableReference (Block block, string name, Location l)
+               {
+                       Block = block;
+                       Name = name;
+                       loc = l;
+                       eclass = ExprClass.Variable;
+               }
+
+               //
+               // Setting `is_readonly' to false will allow you to create a writable
+               // reference to a read-only variable.  This is used by foreach and using.
+               //
+               public LocalVariableReference (Block block, string name, Location l,
+                                              LocalInfo local_info, bool is_readonly)
+                       : this (block, name, l)
+               {
+                       this.local_info = local_info;
+                       this.is_readonly = is_readonly;
+               }
+
+               public VariableInfo VariableInfo {
+                       get {
+                               return local_info.VariableInfo;
+                       }
+               }
+
+               public bool IsReadOnly {
+                       get {
+                               return is_readonly;
+                       }
+               }
+
+               protected Expression DoResolveBase (EmitContext ec, Expression lvalue_right_side)
+               {
+                       if (local_info == null) {
+                               local_info = Block.GetLocalInfo (Name);
+
+                               // is out param
+                               if (lvalue_right_side == EmptyExpression.Null)
+                                       local_info.Used = true;
+
+                               is_readonly = local_info.ReadOnly;
+                       }
+
+                       type = local_info.VariableType;
+
+                       VariableInfo variable_info = local_info.VariableInfo;
+                       if (lvalue_right_side != null){
+                               if (is_readonly){
+                                       Error (1604, "cannot assign to `" + Name + "' because it is readonly");
+                                       return null;
+                               }
+                               
+                               if (variable_info != null)
+                                       variable_info.SetAssigned (ec);
+               }
+               
+                       Expression e = Block.GetConstantExpression (Name);
+                       if (e != null) {
+                               local_info.Used = true;
+                               eclass = ExprClass.Value;
+                               return e.Resolve (ec);
+                       }
+
+                       if ((variable_info != null) && !variable_info.IsAssigned (ec, loc))
+                               return null;
+
+                       if (lvalue_right_side == null)
+                               local_info.Used = true;
+
+                       if (ec.CurrentAnonymousMethod != null){
+                               //
+                               // If we are referencing a variable from the external block
+                               // flag it for capturing
+                               //
+                               if (local_info.Block.Toplevel != ec.CurrentBlock.Toplevel){
+                                       if (local_info.AddressTaken){
+                                               AnonymousMethod.Error_AddressOfCapturedVar (local_info.Name, loc);
+                                               return null;
+                                       }
+                                       ec.CaptureVariable (local_info);
+                               }
+                       }
+                       
+                       return this;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       return DoResolveBase (ec, null);
+               }
+
+               override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       Expression ret = DoResolveBase (ec, right_side);
+                       if (ret != null)
+                               CheckObsoleteAttribute (ret.Type);
+
+                       return ret;
+               }
+
+               public bool VerifyFixed (bool is_expression)
+               {
+                       return !is_expression || local_info.IsFixed;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       if (local_info.FieldBuilder == null){
+                               //
+                               // A local variable on the local CLR stack
+                               //
+                       ig.Emit (OpCodes.Ldloc, local_info.LocalBuilder);
+                       } else {
+                               //
+                               // A local variable captured by anonymous methods.
+                               //
+                               if (!prepared)
+                                       ec.EmitCapturedVariableInstance (local_info);
+                               
+                               ig.Emit (OpCodes.Ldfld, local_info.FieldBuilder);
+                       }
+               }
+               
+               public void Emit (EmitContext ec, bool leave_copy)
+               {
+                       Emit (ec);
+                       if (leave_copy){
+                               ec.ig.Emit (OpCodes.Dup);
+                               if (local_info.FieldBuilder != null){
+                                       temp = new LocalTemporary (ec, Type);
+                                       temp.Store (ec);
+                               }
+                       }
+               }
+               
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+               {
+                       ILGenerator ig = ec.ig;
+                       prepared = prepare_for_load;
+
+                       if (local_info.FieldBuilder == null){
+                               //
+                               // A local variable on the local CLR stack
+                               //
+                               if (local_info.LocalBuilder == null)
+                                       throw new Exception ("This should not happen: both Field and Local are null");
+                               
+                       source.Emit (ec);
+                       if (leave_copy)
+                               ec.ig.Emit (OpCodes.Dup);
+                               ig.Emit (OpCodes.Stloc, local_info.LocalBuilder);
+                       } else {
+                               //
+                               // A local variable captured by anonymous methods or itereators.
+                               //
+                               ec.EmitCapturedVariableInstance (local_info);
+
+                               if (prepare_for_load)
+                                       ig.Emit (OpCodes.Dup);
+                               source.Emit (ec);
+                               if (leave_copy){
+                                       ig.Emit (OpCodes.Dup);
+                                       temp = new LocalTemporary (ec, Type);
+                                       temp.Store (ec);
+                               }
+                               ig.Emit (OpCodes.Stfld, local_info.FieldBuilder);
+                               if (temp != null)
+                                       temp.Emit (ec);
+                       }
+               }
+               
+               public void AddressOf (EmitContext ec, AddressOp mode)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       if (local_info.FieldBuilder == null){
+                               //
+                               // A local variable on the local CLR stack
+                               //
+                       ig.Emit (OpCodes.Ldloca, local_info.LocalBuilder);
+                       } else {
+                               //
+                               // A local variable captured by anonymous methods or iterators
+                               //
+                               ec.EmitCapturedVariableInstance (local_info);
+                               ig.Emit (OpCodes.Ldflda, local_info.FieldBuilder);
+                       }
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("{0} ({1}:{2})", GetType (), Name, loc);
+               }
+       }
+
+       /// <summary>
+       ///   This represents a reference to a parameter in the intermediate
+       ///   representation.
+       /// </summary>
+       public class ParameterReference : Expression, IAssignMethod, IMemoryLocation, IVariable {
+               Parameters pars;
+               String name;
+               int idx;
+               Block block;
+               VariableInfo vi;
+               public Parameter.Modifier mod;
+               public bool is_ref, is_out, prepared;
+
+               public bool IsOut {
+                       get {
+                               return is_out;
+                       }
+               }
+
+               public bool IsRef {
+                       get {
+                               return is_ref;
+                       }
+               }
+
+               LocalTemporary temp;
+               
+               public ParameterReference (Parameters pars, Block block, int idx, string name, Location loc)
+               {
+                       this.pars = pars;
+                       this.block = block;
+                       this.idx  = idx;
+                       this.name = name;
+                       this.loc = loc;
+                       eclass = ExprClass.Variable;
+               }
+
+               public VariableInfo VariableInfo {
+                       get { return vi; }
+               }
+
+               public bool VerifyFixed (bool is_expression)
+               {
+                       return !is_expression || TypeManager.IsValueType (type);
+               }
+
+               public bool IsAssigned (EmitContext ec, Location loc)
+               {
+                       if (!ec.DoFlowAnalysis || !is_out || ec.CurrentBranching.IsAssigned (vi))
+                               return true;
+
+                       Report.Error (165, loc,
+                                     "Use of unassigned parameter `" + name + "'");
+                       return false;
+               }
+
+               public bool IsFieldAssigned (EmitContext ec, string field_name, Location loc)
+               {
+                       if (!ec.DoFlowAnalysis || !is_out || ec.CurrentBranching.IsFieldAssigned (vi, field_name))
+                               return true;
+
+                       Report.Error (170, loc,
+                                     "Use of possibly unassigned field `" + field_name + "'");
+                       return false;
+               }
+
+               public void SetAssigned (EmitContext ec)
+               {
+                       if (is_out && ec.DoFlowAnalysis)
+                               ec.CurrentBranching.SetAssigned (vi);
+               }
+
+               public void SetFieldAssigned (EmitContext ec, string field_name)
+               {
+                       if (is_out && ec.DoFlowAnalysis)
+                               ec.CurrentBranching.SetFieldAssigned (vi, field_name);
+               }
+
+               protected void DoResolveBase (EmitContext ec)
+               {
+                       type = pars.GetParameterInfo (ec, idx, out mod);
+                       is_ref = (mod & Parameter.Modifier.ISBYREF) != 0;
+                       is_out = (mod & Parameter.Modifier.OUT) != 0;
+                       eclass = ExprClass.Variable;
+
+                       if (is_out)
+                               vi = block.ParameterMap [idx];
+
+                       if (ec.CurrentAnonymousMethod != null){
+                               if (is_ref){
+                                       Report.Error (1628, Location,
+                                                     "Can not reference a ref or out parameter in an anonymous method");
+                                       return;
+                               }
+                               
+                               //
+                               // If we are referencing the parameter from the external block
+                               // flag it for capturing
+                               //
+                               //Console.WriteLine ("Is parameter `{0}' local? {1}", name, block.IsLocalParameter (name));
+                               if (!block.IsLocalParameter (name)){
+                                       ec.CaptureParameter (name, type, idx);
+                               }
+                       }
+               }
+
+               //
+               // Notice that for ref/out parameters, the type exposed is not the
+               // same type exposed externally.
+               //
+               // for "ref int a":
+               //   externally we expose "int&"
+               //   here we expose       "int".
+               //
+               // We record this in "is_ref".  This means that the type system can treat
+               // the type as it is expected, but when we generate the code, we generate
+               // the alternate kind of code.
+               //
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       DoResolveBase (ec);
+
+                       if (is_out && ec.DoFlowAnalysis && !IsAssigned (ec, loc))
+                               return null;
+
+                       if (ec.RemapToProxy)
+                               return ec.RemapParameter (idx);
+                       
+                       return this;
+               }
+
+               override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       DoResolveBase (ec);
+
+                       SetAssigned (ec);
+
+                       if (ec.RemapToProxy)
+                               return ec.RemapParameterLValue (idx, right_side);
+                       
+                       return this;
+               }
+
+               static public void EmitLdArg (ILGenerator ig, int x)
+               {
+                       if (x <= 255){
+                               switch (x){
+                               case 0: ig.Emit (OpCodes.Ldarg_0); break;
+                               case 1: ig.Emit (OpCodes.Ldarg_1); break;
+                               case 2: ig.Emit (OpCodes.Ldarg_2); break;
+                               case 3: ig.Emit (OpCodes.Ldarg_3); break;
+                               default: ig.Emit (OpCodes.Ldarg_S, (byte) x); break;
+                               }
+                       } else
+                               ig.Emit (OpCodes.Ldarg, x);
+               }
+               
+               //
+               // This method is used by parameters that are references, that are
+               // being passed as references:  we only want to pass the pointer (that
+               // is already stored in the parameter, not the address of the pointer,
+               // and not the value of the variable).
+               //
+               public void EmitLoad (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       int arg_idx = idx;
+
+                       if (!ec.IsStatic)
+                               arg_idx++;
+
+                       EmitLdArg (ig, arg_idx);
+
+                       //
+                       // FIXME: Review for anonymous methods
+                       //
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)){
+                               ec.EmitParameter (name);
+                               return;
+                       }
+                       
+                       Emit (ec, false);
+               }
+               
+               public void Emit (EmitContext ec, bool leave_copy)
+               {
+                       ILGenerator ig = ec.ig;
+                       int arg_idx = idx;
+
+                       if (!ec.IsStatic)
+                               arg_idx++;
+
+                       EmitLdArg (ig, arg_idx);
+
+                       if (is_ref) {
+                               if (prepared)
+                                       ec.ig.Emit (OpCodes.Dup);
+       
+                               //
+                               // If we are a reference, we loaded on the stack a pointer
+                               // Now lets load the real value
+                               //
+                               LoadFromPtr (ig, type);
+                       }
+                       
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               
+                               if (is_ref) {
+                                       temp = new LocalTemporary (ec, type);
+                                       temp.Store (ec);
+                               }
+                       }
+               }
+               
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+               {
+                       if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)){
+                               ec.EmitAssignParameter (name, source, leave_copy, prepare_for_load);
+                               return;
+                       }
+
+                       ILGenerator ig = ec.ig;
+                       int arg_idx = idx;
+                       
+                       prepared = prepare_for_load;
+                       
+                       if (!ec.IsStatic)
+                               arg_idx++;
+
+                       if (is_ref && !prepared)
+                               EmitLdArg (ig, arg_idx);
+                       
+                       source.Emit (ec);
+
+                       if (leave_copy)
+                               ec.ig.Emit (OpCodes.Dup);
+                       
+                       if (is_ref) {
+                               if (leave_copy) {
+                                       temp = new LocalTemporary (ec, type);
+                                       temp.Store (ec);
+                               }
+                               
+                               StoreFromPtr (ig, type);
+                               
+                               if (temp != null)
+                                       temp.Emit (ec);
+                       } else {
+                               if (arg_idx <= 255)
+                                       ig.Emit (OpCodes.Starg_S, (byte) arg_idx);
+                               else
+                                       ig.Emit (OpCodes.Starg, arg_idx);
+                       }
+               }
+
+               public void AddressOf (EmitContext ec, AddressOp mode)
+               {
+                       if (ec.HaveCaptureInfo && ec.IsParameterCaptured (name)){
+                               ec.EmitAddressOfParameter (name);
+                               return;
+                       }
+                       
+                       int arg_idx = idx;
+
+                       if (!ec.IsStatic)
+                               arg_idx++;
+
+                       if (is_ref){
+                               if (arg_idx <= 255)
+                                       ec.ig.Emit (OpCodes.Ldarg_S, (byte) arg_idx);
+                               else
+                                       ec.ig.Emit (OpCodes.Ldarg, arg_idx);
+                       } else {
+                               if (arg_idx <= 255)
+                                       ec.ig.Emit (OpCodes.Ldarga_S, (byte) arg_idx);
+                               else
+                                       ec.ig.Emit (OpCodes.Ldarga, arg_idx);
+                       }
+               }
+
+       }
+       
+       /// <summary>
+       ///   Used for arguments to New(), Invocation()
+       /// </summary>
+       public class Argument {
+               public enum AType : byte {
+                       Expression,
+                       Ref,
+                       Out,
+                       ArgList,
+                       //FIXME: These two are mbas specific and the
+                       // related changes need to be propagated
+                       NoArg,
+                       AddressOf
+               };
+
+               public readonly AType ArgType;
+               public Expression Expr;
+               
+               public Argument (Expression expr, AType type)
+               {
+                       this.Expr = expr;
+                       this.ArgType = type;
+               }
+
+               public Argument (Expression expr)
+               {
+                       this.Expr = expr;
+                       this.ArgType = AType.Expression;
+               }
+
+               public Type Type {
+                       get {
+                               if (ArgType == AType.Ref || ArgType == AType.Out)
+                                       return TypeManager.GetReferenceType (Expr.Type);
+                               else
+                                       return Expr.Type;
+                       }
+               }
+
+               public Parameter.Modifier GetParameterModifier ()
+               {
+                       switch (ArgType) {
+                       case AType.Out:
+                               return Parameter.Modifier.OUT | Parameter.Modifier.ISBYREF;
+
+                       case AType.Ref:
+                               return Parameter.Modifier.REF | Parameter.Modifier.ISBYREF;
+
+                       default:
+                               return Parameter.Modifier.NONE;
+                       }
+               }
+
+               public static string FullDesc (Argument a)
+               {
+                       if (a.ArgType == AType.ArgList)
+                               return "__arglist";
+
+                       return (a.ArgType == AType.Ref ? "ref " :
+                               (a.ArgType == AType.Out ? "out " : "")) +
+                               TypeManager.CSharpName (a.Expr.Type);
+               }
+
+               public bool ResolveMethodGroup (EmitContext ec, Location loc)
+               {
+                       ConstructedType ctype = Expr as ConstructedType;
+                       if (ctype != null)
+                               Expr = ctype.GetSimpleName (ec);
+
+                       // FIXME: csc doesn't report any error if you try to use `ref' or
+                       //        `out' in a delegate creation expression.
+                       Expr = Expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
+                       if (Expr == null)
+                               return false;
+
+                       return true;
+               }
+               
+               public bool Resolve (EmitContext ec, Location loc)
+               {
+                       if (ArgType == AType.Ref) {
+                               Expr = Expr.Resolve (ec);
+                               if (Expr == null)
+                                       return false;
+
+                               if (!ec.IsConstructor) {
+                                       FieldExpr fe = Expr as FieldExpr;
+                                       if (fe != null && fe.FieldInfo.IsInitOnly) {
+                                               if (fe.FieldInfo.IsStatic)
+                                                       Report.Error (199, loc, "A static readonly field cannot be passed ref or out (except in a static constructor)");
+                                               else
+                                                       Report.Error (192, loc, "A readonly field cannot be passed ref or out (except in a constructor)");
+                                               return false;
+                                       }
+                               }
+                               Expr = Expr.ResolveLValue (ec, Expr);
+                       } else if (ArgType == AType.Out)
+                               Expr = Expr.ResolveLValue (ec, EmptyExpression.Null);
+                       else
+                               Expr = Expr.Resolve (ec);
+
+                       if (Expr == null)
+                               return false;
+
+                       if (ArgType == AType.Expression)
+                               return true;
+                       else {
+                               //
+                               // Catch errors where fields of a MarshalByRefObject are passed as ref or out
+                               // This is only allowed for `this'
+                               //
+                               FieldExpr fe = Expr as FieldExpr;
+                               if (fe != null && !fe.IsStatic){
+                                       Expression instance = fe.InstanceExpression;
+
+                                       if (instance.GetType () != typeof (This)){
+                                               if (fe.InstanceExpression.Type.IsSubclassOf (TypeManager.mbr_type)){
+                                                       Report.SymbolRelatedToPreviousError (fe.InstanceExpression.Type);
+                                                       Report.Error (197, loc, "Cannot pass '{0}' as ref or out or take its address because it is a member of a marshal-by-reference class",
+                                                               fe.Name);
+                                                       return false;
+                                               }
+                                       }
+                               }
+                       }
+
+                       if (Expr.eclass != ExprClass.Variable){
+                               //
+                               // We just probe to match the CSC output
+                               //
+                               if (Expr.eclass == ExprClass.PropertyAccess ||
+                                   Expr.eclass == ExprClass.IndexerAccess){
+                                       Report.Error (
+                                               206, loc,
+                                               "A property or indexer can not be passed as an out or ref " +
+                                               "parameter");
+                               } else {
+                                       Report.Error (
+                                               1510, loc,
+                                               "An lvalue is required as an argument to out or ref");
+                               }
+                               return false;
+                       }
+                               
+                       return true;
+               }
+
+               public void Emit (EmitContext ec)
+               {
+                       //
+                       // Ref and Out parameters need to have their addresses taken.
+                       //
+                       // ParameterReferences might already be references, so we want
+                       // to pass just the value
+                       //
+                       if (ArgType == AType.Ref || ArgType == AType.Out){
+                               AddressOp mode = AddressOp.Store;
+
+                               if (ArgType == AType.Ref)
+                                       mode |= AddressOp.Load;
+                               
+                               if (Expr is ParameterReference){
+                                       ParameterReference pr = (ParameterReference) Expr;
+
+                                       if (pr.IsRef)
+                                               pr.EmitLoad (ec);
+                                       else {
+                                               
+                                               pr.AddressOf (ec, mode);
+                                       }
+                               } else {
+                                       ((IMemoryLocation)Expr).AddressOf (ec, mode);
+                               }
+                       } else
+                               Expr.Emit (ec);
+               }
+       }
+
+       /// <summary>
+       ///   Invocation of methods or delegates.
+       /// </summary>
+       public class Invocation : ExpressionStatement {
+               public readonly ArrayList Arguments;
+
+               public Expression expr;
+               MethodBase method = null;
+               
+               static Hashtable method_parameter_cache;
+
+               static Invocation ()
+               {
+                       method_parameter_cache = new PtrHashtable ();
+               }
+                       
+               //
+               // arguments is an ArrayList, but we do not want to typecast,
+               // as it might be null.
+               //
+               // FIXME: only allow expr to be a method invocation or a
+               // delegate invocation (7.5.5)
+               //
+               public Invocation (Expression expr, ArrayList arguments, Location l)
+               {
+                       this.expr = expr;
+                       Arguments = arguments;
+                       loc = l;
+               }
+
+               public Expression Expr {
+                       get {
+                               return expr;
+                       }
+               }
+
+               /// <summary>
+               ///   Returns the Parameters (a ParameterData interface) for the
+               ///   Method `mb'
+               /// </summary>
+               public static ParameterData GetParameterData (MethodBase mb)
+               {
+                       object pd = method_parameter_cache [mb];
+                       object ip;
+                       
+                       if (pd != null)
+                               return (ParameterData) pd;
+
+                       ip = TypeManager.LookupParametersByBuilder (mb);
+                       if (ip != null){
+                               method_parameter_cache [mb] = ip;
+
+                               return (ParameterData) ip;
+                       } else {
+                               ReflectionParameters rp = new ReflectionParameters (mb);
+                               method_parameter_cache [mb] = rp;
+
+                               return (ParameterData) rp;
+                       }
+               }
+
+               /// <summary>
+               ///   Determines "better conversion" as specified in 7.4.2.3
+               ///
+               ///    Returns : p    if a->p is better,
+               ///              q    if a->q is better,
+               ///              null if neither is better
+               /// </summary>
+               static Type BetterConversion (EmitContext ec, Argument a, Type p, Type q, Location loc)
+               {
+                       Type argument_type = TypeManager.TypeToCoreType (a.Type);
+                       Expression argument_expr = a.Expr;
+
+                       // p = TypeManager.TypeToCoreType (p);
+                       // q = TypeManager.TypeToCoreType (q);
+
+                       if (argument_type == null)
+                               throw new Exception ("Expression of type " + a.Expr +
+                                                     " does not resolve its type");
+
+                       if (p == null || q == null)
+                               throw new InternalErrorException ("BetterConversion Got a null conversion");
+
+                       if (p == q)
+                               return null;
+
+                       if (argument_expr is NullLiteral) {
+                       //
+                               // If the argument is null and one of the types to compare is 'object' and
+                               // the other is a reference type, we prefer the other.
+                       //
+                               // This follows from the usual rules:
+                               //   * There is an implicit conversion from 'null' to type 'object'
+                               //   * There is an implicit conversion from 'null' to any reference type
+                               //   * There is an implicit conversion from any reference type to type 'object'
+                               //   * There is no implicit conversion from type 'object' to other reference types
+                               //  => Conversion of 'null' to a reference type is better than conversion to 'object'
+                               //
+                               //  FIXME: This probably isn't necessary, since the type of a NullLiteral is the 
+                               //         null type. I think it used to be 'object' and thus needed a special 
+                               //         case to avoid the immediately following two checks.
+                               //
+                               if (!p.IsValueType && q == TypeManager.object_type)
+                                       return p;
+                               if (!q.IsValueType && p == TypeManager.object_type)
+                                       return q;
+                       }
+                       
+                       if (argument_type == p)
+                               return p;
+
+                       if (argument_type == q)
+                               return q;
+
+                       Expression p_tmp = new EmptyExpression (p);
+                       Expression q_tmp = new EmptyExpression (q);
+                       
+                       bool p_to_q = Convert.ImplicitConversionExists (ec, p_tmp, q);
+                       bool q_to_p = Convert.ImplicitConversionExists (ec, q_tmp, p);
+
+                       if (p_to_q && !q_to_p)
+                               return p;
+
+                       if (q_to_p && !p_to_q)
+                               return q;
+
+                       if (p == TypeManager.sbyte_type)
+                               if (q == TypeManager.byte_type || q == TypeManager.ushort_type ||
+                                   q == TypeManager.uint32_type || q == TypeManager.uint64_type)
+                                       return p;
+                       if (q == TypeManager.sbyte_type)
+                               if (p == TypeManager.byte_type || p == TypeManager.ushort_type ||
+                                   p == TypeManager.uint32_type || p == TypeManager.uint64_type)
+                                       return q;
+
+                       if (p == TypeManager.short_type)
+                               if (q == TypeManager.ushort_type || q == TypeManager.uint32_type ||
+                                   q == TypeManager.uint64_type)
+                                       return p;
+
+                       if (q == TypeManager.short_type)
+                               if (p == TypeManager.ushort_type || p == TypeManager.uint32_type ||
+                                   p == TypeManager.uint64_type)
+                                       return q;
+
+                       if (p == TypeManager.int32_type)
+                               if (q == TypeManager.uint32_type || q == TypeManager.uint64_type)
+                                       return p;
+
+                       if (q == TypeManager.int32_type)
+                               if (p == TypeManager.uint32_type || p == TypeManager.uint64_type)
+                                       return q;
+
+                       if (p == TypeManager.int64_type)
+                               if (q == TypeManager.uint64_type)
+                                       return p;
+                       if (q == TypeManager.int64_type)
+                               if (p == TypeManager.uint64_type)
+                                       return q;
+
+                       return null;
+               }
+               
+               /// <summary>
+               ///   Determines "Better function" between candidate
+                ///   and the current best match
+               /// </summary>
+               /// <remarks>
+               ///    Returns a boolean indicating :
+               ///     false if candidate ain't better
+               ///     true  if candidate is better than the current best match
+               /// </remarks>
+               static bool BetterFunction (EmitContext ec, ArrayList args, int argument_count,
+                                          MethodBase candidate, bool candidate_params,
+                                          MethodBase best, bool best_params, Location loc)
+               {
+                       ParameterData candidate_pd = GetParameterData (candidate);
+                       ParameterData best_pd = GetParameterData (best);
+               
+                       int cand_count = candidate_pd.Count;
+
+                       //
+                       // If there is no best method, than this one
+                       // is better, however, if we already found a
+                       // best method, we cant tell. This happens
+                       // if we have:
+                       // 
+                       //      interface IFoo {
+                       //              void DoIt ();
+                       //      }
+                       //      
+                       //      interface IBar {
+                       //              void DoIt ();
+                       //      }
+                       //      
+                       //      interface IFooBar : IFoo, IBar {}
+                       //
+                       // We cant tell if IFoo.DoIt is better than IBar.DoIt
+                       //
+                       // However, we have to consider that
+                       // Trim (); is better than Trim (params char[] chars);
+                        //
+                       if (cand_count == 0 && argument_count == 0)
+                               return !candidate_params && best_params;
+
+                       if ((candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.PARAMS) &&
+                           (candidate_pd.ParameterModifier (cand_count - 1) != Parameter.Modifier.ARGLIST))
+                               if (cand_count != argument_count)
+                                       return false;
+
+                       bool better_at_least_one = false;
+                       bool is_equal = true;
+
+                       for (int j = 0; j < argument_count; ++j) {
+                               Argument a = (Argument) args [j];
+
+                               Type ct = TypeManager.TypeToCoreType (candidate_pd.ParameterType (j));
+                               Type bt = TypeManager.TypeToCoreType (best_pd.ParameterType (j));
+
+                               if (candidate_pd.ParameterModifier (j) == Parameter.Modifier.PARAMS)
+                                       if (candidate_params)
+                                               ct = TypeManager.GetElementType (ct);
+
+                               if (best_pd.ParameterModifier (j) == Parameter.Modifier.PARAMS)
+                                       if (best_params)
+                                               bt = TypeManager.GetElementType (bt);
+
+                               if (!ct.Equals (bt))
+                                       is_equal = false;
+
+                               Type better = BetterConversion (ec, a, ct, bt, loc);
+                               // for each argument, the conversion to 'ct' should be no worse than 
+                               // the conversion to 'bt'.
+                               if (better == bt)
+                                       return false;
+                               
+                               // for at least one argument, the conversion to 'ct' should be better than 
+                               // the conversion to 'bt'.
+                               if (better == ct)
+                                       better_at_least_one = true;
+                       }
+
+                        //
+                        // If a method (in the normal form) with the
+                        // same signature as the expanded form of the
+                        // current best params method already exists,
+                        // the expanded form is not applicable so we
+                        // force it to select the candidate
+                        //
+                        if (!candidate_params && best_params && cand_count == argument_count)
+                                return true;
+
+                       //
+                       // If two methods have equal parameter types, but
+                       // only one of them is generic, the non-generic one wins.
+                       //
+                       if (is_equal) {
+                               if (TypeManager.IsGenericMethod (best) && !TypeManager.IsGenericMethod (candidate))
+                                       return true;
+                               else if (!TypeManager.IsGenericMethod (best) && TypeManager.IsGenericMethod (candidate))
+                                       return false;
+                       }
+
+                       return better_at_least_one;
+               }
+
+               public static string FullMethodDesc (MethodBase mb)
+               {
+                       string ret_type = "";
+
+                        if (mb == null)
+                                return "";
+
+                       if (mb is MethodInfo)
+                               ret_type = TypeManager.CSharpName (((MethodInfo) mb).ReturnType);
+                       
+                       StringBuilder sb = new StringBuilder (ret_type);
+                       sb.Append (" ");
+                       sb.Append (mb.ReflectedType.ToString ());
+                       sb.Append (".");
+                       sb.Append (mb.Name);
+                       
+                       ParameterData pd = GetParameterData (mb);
+
+                       int count = pd.Count;
+                       sb.Append (" (");
+                       
+                       for (int i = count; i > 0; ) {
+                               i--;
+
+                               sb.Append (pd.ParameterDesc (count - i - 1));
+                               if (i != 0)
+                                       sb.Append (", ");
+                       }
+                       
+                       sb.Append (")");
+                       return sb.ToString ();
+               }
+
+               public static MethodGroupExpr MakeUnionSet (Expression mg1, Expression mg2, Location loc)
+               {
+                       MemberInfo [] miset;
+                       MethodGroupExpr union;
+
+                       if (mg1 == null) {
+                               if (mg2 == null)
+                                       return null;
+                               return (MethodGroupExpr) mg2;
+                       } else {
+                               if (mg2 == null)
+                                       return (MethodGroupExpr) mg1;
+                       }
+                       
+                       MethodGroupExpr left_set = null, right_set = null;
+                       int length1 = 0, length2 = 0;
+                       
+                       left_set = (MethodGroupExpr) mg1;
+                       length1 = left_set.Methods.Length;
+                       
+                       right_set = (MethodGroupExpr) mg2;
+                       length2 = right_set.Methods.Length;
+                       
+                       ArrayList common = new ArrayList ();
+
+                       foreach (MethodBase r in right_set.Methods){
+                               if (TypeManager.ArrayContainsMethod (left_set.Methods, r))
+                                       common.Add (r);
+                       }
+
+                       miset = new MemberInfo [length1 + length2 - common.Count];
+                       left_set.Methods.CopyTo (miset, 0);
+                       
+                       int k = length1;
+
+                       foreach (MethodBase r in right_set.Methods) {
+                               if (!common.Contains (r))
+                                       miset [k++] = r;
+                       }
+
+                       union = new MethodGroupExpr (miset, loc);
+                       
+                       return union;
+               }
+
+               static bool IsParamsMethodApplicable (EmitContext ec, MethodGroupExpr me,
+                                                     ArrayList arguments, int arg_count,
+                                                     ref MethodBase candidate)
+               {
+                       return IsParamsMethodApplicable (
+                               ec, me, arguments, arg_count, false, ref candidate) ||
+                               IsParamsMethodApplicable (
+                                       ec, me, arguments, arg_count, true, ref candidate);
+
+
+               }
+
+               static bool IsParamsMethodApplicable (EmitContext ec, MethodGroupExpr me,
+                                                     ArrayList arguments, int arg_count,
+                                                     bool do_varargs, ref MethodBase candidate)
+               {
+                       if (!me.HasTypeArguments &&
+                           !TypeManager.InferParamsTypeArguments (ec, arguments, ref candidate))
+                               return false;
+
+                       return IsParamsMethodApplicable (
+                               ec, arguments, arg_count, candidate, do_varargs);
+               }
+
+               /// <summary>
+               ///   Determines if 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,
+                                                     int arg_count, MethodBase candidate,
+                                                     bool do_varargs)
+               {
+                       ParameterData pd = GetParameterData (candidate);
+                       
+                       int pd_count = pd.Count;
+
+                       if (pd_count == 0)
+                               return false;
+                       
+                       int count = pd_count - 1;
+                       if (do_varargs) {
+                               if (pd.ParameterModifier (count) != Parameter.Modifier.ARGLIST)
+                                       return false;
+                               if (pd_count != arg_count)
+                                       return false;
+                       } else {
+                               if (pd.ParameterModifier (count) != Parameter.Modifier.PARAMS)
+                               return false;
+                       }
+                       
+                       if (count > 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 < count; ++i) {
+
+                               Argument a = (Argument) arguments [i];
+
+                               Parameter.Modifier a_mod = a.GetParameterModifier () &
+                                       (unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF)));
+                               Parameter.Modifier p_mod = pd.ParameterModifier (i) &
+                                       (unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF)));
+
+                               if (a_mod == p_mod) {
+
+                                       if (a_mod == Parameter.Modifier.NONE)
+                                               if (!Convert.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.GetReferenceType (pt);
+                                               
+                                               if (pt != a.Type)
+                                                       return false;
+                                       }
+                               } else
+                                       return false;
+                               
+                       }
+
+                       if (do_varargs) {
+                               Argument a = (Argument) arguments [count];
+                               if (!(a.Expr is Arglist))
+                                       return false;
+
+                               return true;
+                       }
+
+                       Type element_type = TypeManager.GetElementType (pd.ParameterType (pd_count - 1));
+
+                       for (int i = pd_count - 1; i < arg_count; i++) {
+                               Argument a = (Argument) arguments [i];
+                               
+                               if (!Convert.ImplicitConversionExists (ec, a.Expr, element_type))
+                                       return false;
+                       }
+                       
+                       return true;
+               }
+
+               static bool IsApplicable (EmitContext ec, MethodGroupExpr me,
+                                         ArrayList arguments, int arg_count,
+                                         ref MethodBase candidate)
+               {
+                       if (!me.HasTypeArguments &&
+                           !TypeManager.InferTypeArguments (ec, arguments, ref candidate))
+                               return false;
+
+                       return IsApplicable (ec, arguments, arg_count, candidate);
+               }
+
+               /// <summary>
+               ///   Determines if the candidate method is applicable (section 14.4.2.1)
+               ///   to the given set of arguments
+               /// </summary>
+               static bool IsApplicable (EmitContext ec, ArrayList arguments, int arg_count,
+                                         MethodBase candidate)
+               {
+                       ParameterData pd = GetParameterData (candidate);
+
+                       if (arg_count != pd.Count)
+                               return false;
+
+                       for (int i = arg_count; i > 0; ) {
+                               i--;
+
+                               Argument a = (Argument) arguments [i];
+
+                               Parameter.Modifier a_mod = a.GetParameterModifier () &
+                                       unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF));
+                               Parameter.Modifier p_mod = pd.ParameterModifier (i) &
+                                       unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF));
+
+
+                               if (a_mod == p_mod ||
+                                   (a_mod == Parameter.Modifier.NONE && p_mod == Parameter.Modifier.PARAMS)) {
+                                       if (a_mod == Parameter.Modifier.NONE) {
+                                                if (!Convert.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.GetReferenceType (pt);
+                                                
+                                               if (pt != a.Type)
+                                                       return false;
+                                       }
+                               } else
+                                       return false;
+                       }
+
+                       return true;
+               }
+               
+               static private bool IsAncestralType (Type first_type, Type second_type)
+               {
+                       return first_type != second_type &&
+                               (second_type.IsSubclassOf (first_type) ||
+                                TypeManager.ImplementsInterface (second_type, first_type));
+               }
+               
+               /// <summary>
+               ///   Find the Applicable Function Members (7.4.2.1)
+               ///
+               ///   me: Method Group expression with the members to select.
+               ///       it might contain constructors or methods (or anything
+               ///       that maps to a method).
+               ///
+               ///   Arguments: ArrayList containing resolved Argument objects.
+               ///
+               ///   loc: The location if we want an error to be reported, or a Null
+               ///        location for "probing" purposes.
+               ///
+               ///   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,
+                                                         ArrayList Arguments, bool may_fail,
+                                                         Location loc)
+               {
+                       MethodBase method = null;
+                       bool method_params = false;
+                       Type applicable_type = null;
+                       int arg_count = 0;
+                       ArrayList candidates = new ArrayList ();
+
+                        //
+                        // Used to keep a map between the candidate
+                        // and whether it is being considered in its
+                        // normal or expanded form
+                        //
+                        // false is normal form, true is expanded form
+                        //
+                        Hashtable candidate_to_form = null;
+
+                       if (Arguments != null)
+                               arg_count = Arguments.Count;
+
+#if REVIEW_IFDEF
+                        if ((me.Name == "Invoke") &&
+                           TypeManager.IsDelegateType (me.DeclaringType)) {
+                                Error_InvokeOnDelegate (loc);
+                                return null;
+                        }
+#endif
+
+                       MethodBase[] methods = me.Methods;
+
+                        //
+                        // First we construct the set of applicable methods
+                        //
+                       bool is_sorted = true;
+                       for (int i = 0; i < methods.Length; i++){
+                                Type decl_type = methods [i].DeclaringType;
+
+                                //
+                                // If we have already found an applicable method
+                                // we eliminate all base types (Section 14.5.5.1)
+                                //
+                                if ((applicable_type != null) &&
+                                   IsAncestralType (decl_type, applicable_type))
+                                       continue;
+
+                               //
+                               // Check if candidate is applicable (section 14.4.2.1)
+                               //   Is candidate applicable in normal form?
+                               //
+                               bool is_applicable = IsApplicable (
+                                       ec, me, Arguments, arg_count, ref methods [i]);
+
+                               if (!is_applicable &&
+                                   (IsParamsMethodApplicable (
+                                           ec, me, Arguments, arg_count, ref methods [i]))) {
+                                       MethodBase candidate = methods [i];
+                                       if (candidate_to_form == null)
+                                               candidate_to_form = new PtrHashtable ();
+                                       candidate_to_form [candidate] = candidate;
+                                       // Candidate is applicable in expanded form
+                                       is_applicable = true;
+                               }
+
+                               if (!is_applicable)
+                                        continue;
+
+                               candidates.Add (methods [i]);
+
+                               if (applicable_type == null)
+                                       applicable_type = decl_type;
+                               else if (applicable_type != decl_type) {
+                                       is_sorted = false;
+                                       if (IsAncestralType (applicable_type, decl_type))
+                                               applicable_type = decl_type;
+                               }
+                       }
+
+                       int candidate_top = candidates.Count;
+
+                       if (candidate_top == 0) {
+                               //
+                               // Okay so we have failed to find anything so we
+                               // return by providing info about the closest match
+                               //
+                               for (int i = 0; i < methods.Length; ++i) {
+                                       MethodBase c = (MethodBase) methods [i];
+                                       ParameterData pd = GetParameterData (c);
+
+                                       if (pd.Count != arg_count)
+                                               continue;
+
+                                       if (!TypeManager.InferTypeArguments (ec, Arguments, ref c))
+                                               continue;
+
+                                       VerifyArgumentsCompat (ec, Arguments, arg_count,
+                                                              c, false, null, may_fail, loc);
+                                        break;
+                               }
+
+                               if (!may_fail) {
+                                       string report_name = me.Name;
+                                       if (report_name == ".ctor")
+                                               report_name = me.DeclaringType.ToString ();
+                                        
+                                       for (int i = 0; i < methods.Length; ++i) {
+                                               MethodBase c = methods [i];
+                                               ParameterData pd = GetParameterData (c);
+
+                                               if (pd.Count != arg_count)
+                                                       continue;
+
+                                               if (TypeManager.InferTypeArguments (ec, Arguments, ref c))
+                                                       continue;
+
+                                               Report.Error (
+                                                       411, loc, "The type arguments for " +
+                                                       "method `{0}' cannot be infered from " +
+                                                       "the usage. Try specifying the type " +
+                                                       "arguments explicitly.", report_name);
+                                               return null;
+                                       }
+
+                                       Error_WrongNumArguments (
+                                               loc, report_name, arg_count);
+                                       return null;
+                               }
+
+                               return null;
+                       }
+
+                       if (!is_sorted) {
+                               //
+                               // At this point, applicable_type is _one_ of the most derived types
+                               // in the set of types containing the methods in this MethodGroup.
+                               // Filter the candidates so that they only contain methods from the
+                               // most derived types.
+                               //
+
+                               int finalized = 0; // Number of finalized candidates
+
+                               do {
+                                       // Invariant: applicable_type is a most derived type
+                                       
+                                       // We'll try to complete Section 14.5.5.1 for 'applicable_type' by 
+                                       // eliminating all it's base types.  At the same time, we'll also move
+                                       // every unrelated type to the end of the array, and pick the next
+                                       // 'applicable_type'.
+
+                                       Type next_applicable_type = null;
+                                       int j = finalized; // where to put the next finalized candidate
+                                       int k = finalized; // where to put the next undiscarded candidate
+                                       for (int i = finalized; i < candidate_top; ++i) {
+                                               Type decl_type = ((MethodBase) candidates[i]).DeclaringType;
+
+                                               if (decl_type == applicable_type) {
+                                                       candidates[k++] = candidates[j];
+                                                       candidates[j++] = candidates[i];
+                                                       continue;
+                                               }
+
+                                               if (IsAncestralType (decl_type, applicable_type))
+                                                       continue;
+
+                                               if (next_applicable_type != null &&
+                                                   IsAncestralType (decl_type, next_applicable_type))
+                                                       continue;
+
+                                               candidates[k++] = candidates[i];
+
+                                               if (next_applicable_type == null ||
+                                                   IsAncestralType (next_applicable_type, decl_type))
+                                                       next_applicable_type = decl_type;
+                                       }
+
+                                       applicable_type = next_applicable_type;
+                                       finalized = j;
+                                       candidate_top = k;
+                               } while (applicable_type != null);
+                       }
+
+                        //
+                        // Now we actually find the best method
+                        //
+
+                       method = (MethodBase) candidates[0];
+                       method_params = candidate_to_form != null && candidate_to_form.Contains (method);
+                       for (int ix = 1; ix < candidate_top; ix++){
+                               MethodBase candidate = (MethodBase) candidates [ix];
+                               bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
+
+                               if (BetterFunction (ec, Arguments, arg_count, 
+                                                   candidate, cand_params,
+                                                   method, method_params, loc)) {
+                                       method = candidate;
+                                       method_params = cand_params;
+                               }
+                       }
+
+                       //
+                       // Now check that there are no ambiguities i.e the selected method
+                       // should be better than all the others
+                       //
+                       bool ambiguous = false;
+                       for (int ix = 0; ix < candidate_top; ix++){
+                               MethodBase candidate = (MethodBase) candidates [ix];
+
+                                if (candidate == method)
+                                        continue;
+
+                                bool cand_params = candidate_to_form != null && candidate_to_form.Contains (candidate);
+                               if (!BetterFunction (ec, Arguments, arg_count,
+                                                   method, method_params,
+                                                   candidate, cand_params,
+                                                    loc)) {
+                                       Report.SymbolRelatedToPreviousError (candidate);
+                                       ambiguous = true;
+                               }
+                       }
+
+                       if (ambiguous) {
+                               Report.SymbolRelatedToPreviousError (method);
+                               Report.Error (121, loc, "Ambiguous call when selecting function due to implicit casts");                                        
+                               return null;
+                       }
+
+                       //
+                       // And now check if the arguments are all
+                       // compatible, perform conversions if
+                       // necessary etc. and return if everything is
+                       // all right
+                       //
+                        if (!VerifyArgumentsCompat (ec, Arguments, arg_count, method,
+                                                    method_params, null, may_fail, loc))
+                               return null;
+
+                       return method;
+               }
+
+                static void Error_WrongNumArguments (Location loc, String name, int arg_count)
+                {
+                        Report.Error (1501, loc,
+                                      "No overload for method `" + name + "' takes `" +
+                                      arg_count + "' arguments");
+                }
+
+                static void Error_InvokeOnDelegate (Location loc)
+                {
+                        Report.Error (1533, loc,
+                                      "Invoke cannot be called directly on a delegate");
+                }
+                        
+               static void Error_InvalidArguments (Location loc, int idx, MethodBase method,
+                                                    Type delegate_type, string arg_sig, string par_desc)
+               {
+                       if (delegate_type == null) 
+                               Report.Error (1502, loc,
+                                             "The best overloaded match for method '" +
+                                             FullMethodDesc (method) +
+                                             "' has some invalid arguments");
+                       else
+                               Report.Error (1594, loc,
+                                             "Delegate '" + delegate_type.ToString () +
+                                             "' has some invalid arguments.");
+                       Report.Error (1503, loc,
+                                     String.Format ("Argument {0}: Cannot convert from '{1}' to '{2}'",
+                                                    idx, arg_sig, par_desc));
+               }
+               
+               public static bool VerifyArgumentsCompat (EmitContext ec, ArrayList Arguments,
+                                                         int arg_count, MethodBase method, 
+                                                         bool chose_params_expanded,
+                                                         Type delegate_type, bool may_fail,
+                                                         Location loc)
+               {
+                       ParameterData pd = GetParameterData (method);
+                       int pd_count = pd.Count;
+                       
+                       for (int j = 0; j < arg_count; j++) {
+                               Argument a = (Argument) Arguments [j];
+                               Expression a_expr = a.Expr;
+                               Type parameter_type = pd.ParameterType (j);
+                               Parameter.Modifier pm = pd.ParameterModifier (j);
+                               
+                               if (pm == Parameter.Modifier.PARAMS){
+                                       if ((pm & ~Parameter.Modifier.PARAMS) != a.GetParameterModifier ()) {
+                                               if (!may_fail)
+                                                       Error_InvalidArguments (
+                                                               loc, j, method, delegate_type,
+                                                               Argument.FullDesc (a), pd.ParameterDesc (j));
+                                               return false;
+                                       }
+
+                                       if (chose_params_expanded)
+                                               parameter_type = TypeManager.GetElementType (parameter_type);
+                               } else if (pm == Parameter.Modifier.ARGLIST){
+                                       continue;
+                               } else {
+                                       //
+                                       // Check modifiers
+                                       //
+                                       if (pd.ParameterModifier (j) != a.GetParameterModifier ()){
+                                               if (!may_fail)
+                                                       Error_InvalidArguments (
+                                                               loc, j, method, delegate_type,
+                                                               Argument.FullDesc (a), pd.ParameterDesc (j));
+                                               return false;
+                                       }
+                               }
+
+                               //
+                               // Check Type
+                               //
+                               if (!TypeManager.IsEqual (a.Type, parameter_type)){
+                                       Expression conv;
+
+                                       conv = Convert.ImplicitConversion (ec, a_expr, parameter_type, loc);
+
+                                       if (conv == null) {
+                                               if (!may_fail)
+                                                       Error_InvalidArguments (
+                                                               loc, j, method, delegate_type,
+                                                               Argument.FullDesc (a), pd.ParameterDesc (j));
+                                               return false;
+                                       }
+                                       
+                                       //
+                                       // Update the argument with the implicit conversion
+                                       //
+                                       if (a_expr != conv)
+                                               a.Expr = conv;
+                               }
+
+                               if (parameter_type.IsPointer){
+                                       if (!ec.InUnsafe){
+                                               UnsafeError (loc);
+                                               return false;
+                                       }
+                               }
+                               
+                               Parameter.Modifier a_mod = a.GetParameterModifier () &
+                                       unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF));
+                               Parameter.Modifier p_mod = pd.ParameterModifier (j) &
+                                       unchecked (~(Parameter.Modifier.OUT | Parameter.Modifier.REF));
+                               
+                               if (a_mod != p_mod &&
+                                   pd.ParameterModifier (pd_count - 1) != Parameter.Modifier.PARAMS) {
+                                       if (!may_fail) {
+                                               Report.Error (1502, loc,
+                                                      "The best overloaded match for method '" + FullMethodDesc (method)+
+                                                      "' has some invalid arguments");
+                                               Report.Error (1503, loc,
+                                                      "Argument " + (j+1) +
+                                                      ": Cannot convert from '" + Argument.FullDesc (a) 
+                                                      + "' to '" + pd.ParameterDesc (j) + "'");
+                                       }
+                                       
+                                       return false;
+                               }
+                       }
+
+                       return true;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       //
+                       // First, resolve the expression that is used to
+                       // trigger the invocation
+                       //
+                       if (expr is ConstructedType)
+                               expr = ((ConstructedType) expr).GetSimpleName (ec);
+
+                       expr = expr.Resolve (ec, ResolveFlags.VariableOrValue | ResolveFlags.MethodGroup);
+                       if (expr == null)
+                               return null;
+
+                       if (!(expr is MethodGroupExpr)) {
+                               Type expr_type = expr.Type;
+
+                               if (expr_type != null){
+                                       bool IsDelegate = TypeManager.IsDelegateType (expr_type);
+                                       if (IsDelegate)
+                                               return (new DelegateInvocation (
+                                                       this.expr, Arguments, loc)).Resolve (ec);
+                               }
+                       }
+
+                       if (!(expr is MethodGroupExpr)){
+                               expr.Error_UnexpectedKind (ResolveFlags.MethodGroup, loc);
+                               return null;
+                       }
+
+                       //
+                       // Next, evaluate all the expressions in the argument list
+                       //
+                       if (Arguments != null){
+                               foreach (Argument a in Arguments){
+                                       if (!a.Resolve (ec, loc))
+                                               return null;
+                               }
+                       }
+
+                       MethodGroupExpr mg = (MethodGroupExpr) expr;
+                       method = OverloadResolve (ec, mg, Arguments, false, loc);
+
+                       if (method == null)
+                               return null;
+
+                       MethodInfo mi = method as MethodInfo;
+                       if (mi != null) {
+                               type = TypeManager.TypeToCoreType (mi.ReturnType);
+                               if (!mi.IsStatic && !mg.IsExplicitImpl && (mg.InstanceExpression == null)) {
+                                       SimpleName.Error_ObjectRefRequired (ec, loc, mi.Name);
+                                       return null;
+                               }
+
+                               Expression iexpr = mg.InstanceExpression;
+                               if (mi.IsStatic && (iexpr != null) && !(iexpr is This)) {
+                                       if (mg.IdenticalTypeName)
+                                               mg.InstanceExpression = null;
+                                       else {
+                                               MemberAccess.error176 (loc, mi.Name);
+                                               return null;
+                                       }
+                               }
+                       }
+
+                       if (type.IsPointer){
+                               if (!ec.InUnsafe){
+                                       UnsafeError (loc);
+                                       return null;
+                               }
+                       }
+                       
+                       //
+                       // Only base will allow this invocation to happen.
+                       //
+                       if (mg.IsBase && method.IsAbstract){
+                               Report.Error (205, loc, "Cannot call an abstract base member: " +
+                                             FullMethodDesc (method));
+                               return null;
+                       }
+
+                       if (method.Name == "Finalize" && Arguments == null) {
+                               if (mg.IsBase)
+                                       Report.Error (250, loc, "Do not directly call your base class Finalize method. It is called automatically from your destructor");
+                               else
+                                       Report.Error (245, loc, "Destructors and object.Finalize cannot be called directly. Consider calling IDisposable.Dispose if available");
+                               return null;
+                       }
+
+                       if ((method.Attributes & MethodAttributes.SpecialName) != 0){
+                               if (TypeManager.LookupDeclSpace (method.DeclaringType) != null || TypeManager.IsSpecialMethod (method)) {
+                                       Report.Error (571, loc, TypeManager.CSharpSignature (method) + ": can not call operator or accessor");
+                                       return null;
+                               }
+                       }
+                       
+                       if (mg.InstanceExpression != null)
+                               mg.InstanceExpression.CheckMarshallByRefAccess (ec.ContainerType);
+
+                       eclass = ExprClass.Value;
+                       return this;
+               }
+
+               // <summary>
+               //   Emits the list of arguments as an array
+               // </summary>
+               static void EmitParams (EmitContext ec, int idx, ArrayList arguments)
+               {
+                       ILGenerator ig = ec.ig;
+                       int count = arguments.Count - idx;
+                       Argument a = (Argument) arguments [idx];
+                       Type t = a.Expr.Type;
+
+                       IntConstant.EmitInt (ig, count);
+                       ig.Emit (OpCodes.Newarr, TypeManager.TypeToCoreType (t));
+
+                       int top = arguments.Count;
+                       for (int j = idx; j < top; j++){
+                               a = (Argument) arguments [j];
+                               
+                               ig.Emit (OpCodes.Dup);
+                               IntConstant.EmitInt (ig, j - idx);
+
+                               bool is_stobj, has_type_arg;
+                               OpCode op = ArrayAccess.GetStoreOpcode (t, out is_stobj, out has_type_arg);
+                               if (is_stobj)
+                                       ig.Emit (OpCodes.Ldelema, t);
+
+                               a.Emit (ec);
+
+                               if (has_type_arg)
+                                       ig.Emit (op, t);
+                               else
+                                       ig.Emit (op);
+                       }
+               }
+               
+               /// <summary>
+               ///   Emits a list of resolved Arguments that are in the arguments
+               ///   ArrayList.
+               /// 
+               ///   The MethodBase argument might be null if the
+               ///   emission of the arguments is known not to contain
+               ///   a `params' field (for example in constructors or other routines
+               ///   that keep their arguments in this structure)
+               ///   
+               ///   if `dup_args' is true, a copy of the arguments will be left
+               ///   on the stack. If `dup_args' is true, you can specify `this_arg'
+               ///   which will be duplicated before any other args. Only EmitCall
+               ///   should be using this interface.
+               /// </summary>
+               public static void EmitArguments (EmitContext ec, MethodBase mb, ArrayList arguments, bool dup_args, LocalTemporary this_arg)
+               {
+                       ParameterData pd;
+                       if (mb != null)
+                               pd = GetParameterData (mb);
+                       else
+                               pd = null;
+                       
+                       LocalTemporary [] temps = null;
+                       
+                       if (dup_args)
+                               temps = new LocalTemporary [arguments.Count];
+
+                       //
+                       // If we are calling a params method with no arguments, special case it
+                       //
+                       if (arguments == null){
+                               if (pd != null && pd.Count > 0 &&
+                                   pd.ParameterModifier (0) == Parameter.Modifier.PARAMS){
+                                       ILGenerator ig = ec.ig;
+
+                                       IntConstant.EmitInt (ig, 0);
+                                       ig.Emit (OpCodes.Newarr, TypeManager.GetElementType (pd.ParameterType (0)));
+                               }
+
+                               return;
+                       }
+
+                       int top = arguments.Count;
+
+                       for (int i = 0; i < top; i++){
+                               Argument a = (Argument) arguments [i];
+
+                               if (pd != null){
+                                       if (pd.ParameterModifier (i) == Parameter.Modifier.PARAMS){
+                                               //
+                                               // Special case if we are passing the same data as the
+                                               // params argument, do not put it in an array.
+                                               //
+                                               if (pd.ParameterType (i) == a.Type)
+                                                       a.Emit (ec);
+                                               else
+                                                       EmitParams (ec, i, arguments);
+                                               return;
+                                       }
+                               }
+                                           
+                               a.Emit (ec);
+                               if (dup_args) {
+                                       ec.ig.Emit (OpCodes.Dup);
+                                       (temps [i] = new LocalTemporary (ec, a.Type)).Store (ec);
+                               }
+                       }
+                       
+                       if (dup_args) {
+                               if (this_arg != null)
+                                       this_arg.Emit (ec);
+                               
+                               for (int i = 0; i < top; i ++)
+                                       temps [i].Emit (ec);
+                       }
+
+                       if (pd != null && pd.Count > top &&
+                           pd.ParameterModifier (top) == Parameter.Modifier.PARAMS){
+                               ILGenerator ig = ec.ig;
+
+                               IntConstant.EmitInt (ig, 0);
+                               ig.Emit (OpCodes.Newarr, TypeManager.GetElementType (pd.ParameterType (top)));
+                       }
+               }
+
+               static Type[] GetVarargsTypes (EmitContext ec, MethodBase mb,
+                                              ArrayList arguments)
+               {
+                       ParameterData pd = GetParameterData (mb);
+
+                       if (arguments == null)
+                               return new Type [0];
+
+                       Argument a = (Argument) arguments [pd.Count - 1];
+                       Arglist list = (Arglist) a.Expr;
+
+                       return list.ArgumentTypes;
+               }
+
+               /// <summary>
+               /// This checks the ConditionalAttribute on the method 
+               /// </summary>
+               static bool IsMethodExcluded (MethodBase method, EmitContext ec)
+               {
+                       if (method.IsConstructor)
+                               return false;
+
+                       IMethodData md = TypeManager.GetMethod (method);
+                       if (md != null)
+                               return md.IsExcluded (ec);
+
+                       // For some methods (generated by delegate class) GetMethod returns null
+                       // because they are not included in builder_to_method table
+                       if (method.DeclaringType is TypeBuilder)
+                               return false;
+
+                       return AttributeTester.IsConditionalMethodExcluded (method);
+               }
+
+               /// <remarks>
+               ///   is_base tells whether we want to force the use of the `call'
+               ///   opcode instead of using callvirt.  Call is required to call
+               ///   a specific method, while callvirt will always use the most
+               ///   recent method in the vtable.
+               ///
+               ///   is_static tells whether this is an invocation on a static method
+               ///
+               ///   instance_expr is an expression that represents the instance
+               ///   it must be non-null if is_static is false.
+               ///
+               ///   method is the method to invoke.
+               ///
+               ///   Arguments is the list of arguments to pass to the method or constructor.
+               /// </remarks>
+               public static void EmitCall (EmitContext ec, bool is_base,
+                                            bool is_static, Expression instance_expr,
+                                            MethodBase method, ArrayList Arguments, Location loc)
+               {
+                       EmitCall (ec, is_base, is_static, instance_expr, method, Arguments, loc, false, false);
+               }
+               
+               // `dup_args' leaves an extra copy of the arguments on the stack
+               // `omit_args' does not leave any arguments at all.
+               // So, basically, you could make one call with `dup_args' set to true,
+               // and then another with `omit_args' set to true, and the two calls
+               // would have the same set of arguments. However, each argument would
+               // only have been evaluated once.
+               public static void EmitCall (EmitContext ec, bool is_base,
+                                            bool is_static, Expression instance_expr,
+                                            MethodBase method, ArrayList Arguments, Location loc,
+                                            bool dup_args, bool omit_args)
+               {
+                       ILGenerator ig = ec.ig;
+                       bool struct_call = false;
+                       bool this_call = false;
+                       LocalTemporary this_arg = null;
+
+                       Type decl_type = method.DeclaringType;
+
+                       if (!RootContext.StdLib) {
+                               // Replace any calls to the system's System.Array type with calls to
+                               // the newly created one.
+                               if (method == TypeManager.system_int_array_get_length)
+                                       method = TypeManager.int_array_get_length;
+                               else if (method == TypeManager.system_int_array_get_rank)
+                                       method = TypeManager.int_array_get_rank;
+                               else if (method == TypeManager.system_object_array_clone)
+                                       method = TypeManager.object_array_clone;
+                               else if (method == TypeManager.system_int_array_get_length_int)
+                                       method = TypeManager.int_array_get_length_int;
+                               else if (method == TypeManager.system_int_array_get_lower_bound_int)
+                                       method = TypeManager.int_array_get_lower_bound_int;
+                               else if (method == TypeManager.system_int_array_get_upper_bound_int)
+                                       method = TypeManager.int_array_get_upper_bound_int;
+                               else if (method == TypeManager.system_void_array_copyto_array_int)
+                                       method = TypeManager.void_array_copyto_array_int;
+                       }
+
+                       if (ec.TestObsoleteMethodUsage) {
+                               //
+                               // This checks ObsoleteAttribute on the method and on the declaring type
+                               //
+                               ObsoleteAttribute oa = AttributeTester.GetMethodObsoleteAttribute (method);
+                               if (oa != null)
+                                       AttributeTester.Report_ObsoleteMessage (oa, TypeManager.CSharpSignature (method), loc);
+
+                               oa = AttributeTester.GetObsoleteAttribute (method.DeclaringType);
+                               if (oa != null) {
+                                       AttributeTester.Report_ObsoleteMessage (oa, method.DeclaringType.FullName, loc);
+                               }
+                       }
+
+                       if (IsMethodExcluded (method, ec))
+                               return;
+                       
+                       if (!is_static){
+                               this_call = instance_expr == null;
+                               if (decl_type.IsValueType || (!this_call && instance_expr.Type.IsValueType))
+                                       struct_call = true;
+
+                               //
+                               // If this is ourselves, push "this"
+                               //
+                               if (!omit_args) {
+                                       Type t = null;
+                                       if (this_call) {
+                                               ig.Emit (OpCodes.Ldarg_0);
+                                               t = decl_type;
+                                       } else {
+                                               Type iexpr_type = instance_expr.Type;
+
+                                               //
+                                               // Push the instance expression
+                                               //
+                                               if (TypeManager.IsValueType (iexpr_type)) {
+                                                       //
+                                                       // Special case: calls to a function declared in a 
+                                                       // reference-type with a value-type argument need
+                                                       // to have their value boxed.
+                                                       if (decl_type.IsValueType ||
+                                                           iexpr_type.IsGenericParameter) {
+                                                               //
+                                                               // If the expression implements IMemoryLocation, then
+                                                               // we can optimize and use AddressOf on the
+                                                               // return.
+                                                               //
+                                                               // If not we have to use some temporary storage for
+                                                               // it.
+                                                               if (instance_expr is IMemoryLocation) {
+                                                                       ((IMemoryLocation)instance_expr).
+                                                                               AddressOf (ec, AddressOp.LoadStore);
+                                                               } else {
+                                                                       LocalTemporary temp = new LocalTemporary (ec, iexpr_type);
+                                                                       instance_expr.Emit (ec);
+                                                                       temp.Store (ec);
+                                                                       temp.AddressOf (ec, AddressOp.Load);
+                                                               }
+
+                                                               // avoid the overhead of doing this all the time.
+                                                               if (dup_args)
+                                                                       t = TypeManager.GetReferenceType (iexpr_type);
+                                                       } else {
+                                                               instance_expr.Emit (ec);
+                                                               ig.Emit (OpCodes.Box, instance_expr.Type);
+                                                               t = TypeManager.object_type;
+                                                       }
+                                               } else {
+                                                       instance_expr.Emit (ec);
+                                                       t = instance_expr.Type;
+                                               }
+                                       }
+
+                                       if (dup_args) {
+                                               this_arg = new LocalTemporary (ec, t);
+                                               ig.Emit (OpCodes.Dup);
+                                               this_arg.Store (ec);
+                                       }
+                               }
+                       }
+
+                       if (!omit_args)
+                               EmitArguments (ec, method, Arguments, dup_args, this_arg);
+
+                       if ((instance_expr != null) && (instance_expr.Type.IsGenericParameter))
+                               ig.Emit (OpCodes.Constrained, instance_expr.Type);
+
+                       OpCode call_op;
+                       if (is_static || struct_call || is_base || (this_call && !method.IsVirtual))
+                               call_op = OpCodes.Call;
+                       else
+                               call_op = OpCodes.Callvirt;
+
+                       if ((method.CallingConvention & CallingConventions.VarArgs) != 0) {
+                               Type[] varargs_types = GetVarargsTypes (ec, method, Arguments);
+                               ig.EmitCall (call_op, (MethodInfo) method, varargs_types);
+                               return;
+                       }
+
+                       //
+                       // If you have:
+                       // this.DoFoo ();
+                       // and DoFoo is not virtual, you can omit the callvirt,
+                       // because you don't need the null checking behavior.
+                       //
+                       if (method is MethodInfo)
+                               ig.Emit (call_op, (MethodInfo) method);
+                       else
+                               ig.Emit (call_op, (ConstructorInfo) method);
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       MethodGroupExpr mg = (MethodGroupExpr) this.expr;
+
+                       EmitCall (ec, mg.IsBase, method.IsStatic, mg.InstanceExpression, method, Arguments, loc);
+               }
+               
+               public override void EmitStatement (EmitContext ec)
+               {
+                       Emit (ec);
+
+                       // 
+                       // Pop the return value if there is one
+                       //
+                       if (method is MethodInfo){
+                               Type ret = ((MethodInfo)method).ReturnType;
+                               if (TypeManager.TypeToCoreType (ret) != TypeManager.void_type)
+                                       ec.ig.Emit (OpCodes.Pop);
+                       }
+               }
+       }
+
+       public class InvocationOrCast : ExpressionStatement
+       {
+               Expression expr;
+               Expression argument;
+
+               public InvocationOrCast (Expression expr, Expression argument, Location loc)
+               {
+                       this.expr = expr;
+                       this.argument = argument;
+                       this.loc = loc;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       //
+                       // First try to resolve it as a cast.
+                       //
+                       TypeExpr te = expr.ResolveAsTypeStep (ec) as TypeExpr;
+                       if ((te != null) && (te.eclass == ExprClass.Type)) {
+                               Cast cast = new Cast (te, argument, loc);
+                               return cast.Resolve (ec);
+                       }
+
+                       //
+                       // This can either be a type or a delegate invocation.
+                       // Let's just resolve it and see what we'll get.
+                       //
+                       expr = expr.Resolve (ec, ResolveFlags.Type | ResolveFlags.VariableOrValue);
+                       if (expr == null)
+                               return null;
+
+                       //
+                       // Ok, so it's a Cast.
+                       //
+                       if (expr.eclass == ExprClass.Type) {
+                               Cast cast = new Cast (new TypeExpression (expr.Type, loc), argument, loc);
+                               return cast.Resolve (ec);
+                       }
+
+                       //
+                       // It's a delegate invocation.
+                       //
+                       if (!TypeManager.IsDelegateType (expr.Type)) {
+                               Error (149, "Method name expected");
+                               return null;
+                       }
+
+                       ArrayList args = new ArrayList ();
+                       args.Add (new Argument (argument, Argument.AType.Expression));
+                       DelegateInvocation invocation = new DelegateInvocation (expr, args, loc);
+                       return invocation.Resolve (ec);
+               }
+
+               void error201 ()
+               {
+                       Error (201, "Only assignment, call, increment, decrement and new object " +
+                              "expressions can be used as a statement");
+               }
+
+               public override ExpressionStatement ResolveStatement (EmitContext ec)
+               {
+                       //
+                       // First try to resolve it as a cast.
+                       //
+                       TypeExpr te = expr.ResolveAsTypeStep (ec) as TypeExpr;
+                       if ((te != null) && (te.eclass == ExprClass.Type)) {
+                               error201 ();
+                               return null;
+                       }
+
+                       //
+                       // This can either be a type or a delegate invocation.
+                       // Let's just resolve it and see what we'll get.
+                       //
+                       expr = expr.Resolve (ec, ResolveFlags.Type | ResolveFlags.VariableOrValue);
+                       if ((expr == null) || (expr.eclass == ExprClass.Type)) {
+                               error201 ();
+                               return null;
+                       }
+
+                       //
+                       // It's a delegate invocation.
+                       //
+                       if (!TypeManager.IsDelegateType (expr.Type)) {
+                               Error (149, "Method name expected");
+                               return null;
+                       }
+
+                       ArrayList args = new ArrayList ();
+                       args.Add (new Argument (argument, Argument.AType.Expression));
+                       DelegateInvocation invocation = new DelegateInvocation (expr, args, loc);
+                       return invocation.ResolveStatement (ec);
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new Exception ("Cannot happen");
+               }
+
+               public override void EmitStatement (EmitContext ec)
+               {
+                       throw new Exception ("Cannot happen");
+               }
+       }
+
+       //
+       // This class is used to "disable" the code generation for the
+       // temporary variable when initializing value types.
+       //
+       class EmptyAddressOf : EmptyExpression, IMemoryLocation {
+               public void AddressOf (EmitContext ec, AddressOp Mode)
+               {
+                       // nothing
+               }
+       }
+       
+       /// <summary>
+       ///    Implements the new expression 
+       /// </summary>
+       public class New : ExpressionStatement, IMemoryLocation {
+               public readonly ArrayList Arguments;
+
+               //
+               // During bootstrap, it contains the RequestedType,
+               // but if `type' is not null, it *might* contain a NewDelegate
+               // (because of field multi-initialization)
+               //
+               public Expression RequestedType;
+
+               MethodBase method = null;
+
+               //
+               // If set, the new expression is for a value_target, and
+               // we will not leave anything on the stack.
+               //
+               Expression value_target;
+               bool value_target_set = false;
+               bool is_type_parameter = false;
+               
+               public New (Expression requested_type, ArrayList arguments, Location l)
+               {
+                       RequestedType = requested_type;
+                       Arguments = arguments;
+                       loc = l;
+               }
+
+               public bool SetValueTypeVariable (Expression value)
+               {
+                       value_target = value;
+                       value_target_set = true;
+                       if (!(value_target is IMemoryLocation)){
+                               Error_UnexpectedKind ("variable", loc);
+                               return false;
+                       }
+                       return true;
+               }
+
+               //
+               // This function is used to disable the following code sequence for
+               // value type initialization:
+               //
+               // AddressOf (temporary)
+               // Construct/Init
+               // LoadTemporary
+               //
+               // Instead the provide will have provided us with the address on the
+               // stack to store the results.
+               //
+               static Expression MyEmptyExpression;
+               
+               public void DisableTemporaryValueType ()
+               {
+                       if (MyEmptyExpression == null)
+                               MyEmptyExpression = new EmptyAddressOf ();
+
+                       //
+                       // To enable this, look into:
+                       // test-34 and test-89 and self bootstrapping.
+                       //
+                       // For instance, we can avoid a copy by using `newobj'
+                       // instead of Call + Push-temp on value types.
+//                     value_target = MyEmptyExpression;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       //
+                       // The New DoResolve might be called twice when initializing field
+                       // expressions (see EmitFieldInitializers, the call to
+                       // GetInitializerExpression will perform a resolve on the expression,
+                       // and later the assign will trigger another resolution
+                       //
+                       // This leads to bugs (#37014)
+                       //
+                       if (type != null){
+                               if (RequestedType is NewDelegate)
+                                       return RequestedType;
+                               return this;
+                       }
+                       
+                       TypeExpr texpr = RequestedType.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return null;
+                       
+                       type = texpr.Type;
+                       if (type == null)
+                               return null;
+                       
+                       CheckObsoleteAttribute (type);
+
+                       bool IsDelegate = TypeManager.IsDelegateType (type);
+                       
+                       if (IsDelegate){
+                               RequestedType = (new NewDelegate (type, Arguments, loc)).Resolve (ec);
+                               if (RequestedType != null)
+                                       if (!(RequestedType is DelegateCreation))
+                                               throw new Exception ("NewDelegate.Resolve returned a non NewDelegate: " + RequestedType.GetType ());
+                               return RequestedType;
+                       }
+
+                       if (type.IsGenericParameter) {
+                               if (!TypeManager.HasConstructorConstraint (type)) {
+                                       Error (304, String.Format (
+                                                      "Cannot create an instance of the " +
+                                                      "variable type '{0}' because it " +
+                                                      "doesn't have the new() constraint",
+                                                      type));
+                                       return null;
+                               }
+
+                               if ((Arguments != null) && (Arguments.Count != 0)) {
+                                       Error (417, String.Format (
+                                                      "`{0}': cannot provide arguments " +
+                                                      "when creating an instance of a " +
+                                                      "variable type.", type));
+                                       return null;
+                               }
+
+                               is_type_parameter = true;
+                               eclass = ExprClass.Value;
+                               return this;
+                       }
+
+                       if (type.IsInterface || type.IsAbstract){
+                               Error (144, "It is not possible to create instances of interfaces or abstract classes");
+                               return null;
+                       }
+
+                       if (type.IsAbstract && type.IsSealed) {
+                               Report.Error (712, loc, "Cannot create an instance of the static class '{0}'", TypeManager.CSharpName (type));
+                               return null;
+                       }
+
+                       bool is_struct = type.IsValueType;
+                       eclass = ExprClass.Value;
+
+                       //
+                       // SRE returns a match for .ctor () on structs (the object constructor), 
+                       // so we have to manually ignore it.
+                       //
+                       if (is_struct && Arguments == null)
+                               return this;
+
+                       Expression ml;
+                       ml = MemberLookupFinal (ec, type, type, ".ctor",
+                                               // For member-lookup, treat 'new Foo (bar)' as call to 'foo.ctor (bar)', where 'foo' is of type 'Foo'.
+                                               MemberTypes.Constructor,
+                                               AllBindingFlags | BindingFlags.DeclaredOnly, loc);
+
+                       if (ml == null)
+                               return null;
+                       
+                       if (! (ml is MethodGroupExpr)){
+                               if (!is_struct){
+                                       ml.Error_UnexpectedKind ("method group", loc);
+                                       return null;
+                               }
+                       }
+
+                       if (ml != null) {
+                               if (Arguments != null){
+                                       foreach (Argument a in Arguments){
+                                               if (!a.Resolve (ec, loc))
+                                                       return null;
+                                       }
+                               }
+
+                               method = Invocation.OverloadResolve (
+                                       ec, (MethodGroupExpr) ml, Arguments, false, loc);
+                               
+                       }
+
+                       if (method == null) { 
+                                if (!is_struct || Arguments.Count > 0) {
+                                       Error (1501, String.Format (
+                                           "New invocation: Can not find a constructor in `{0}' for this argument list",
+                                           TypeManager.CSharpName (type)));
+                                       return null;
+                                }
+                       }
+
+                       return this;
+               }
+
+               bool DoEmitTypeParameter (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       ig.Emit (OpCodes.Ldtoken, type);
+                       ig.Emit (OpCodes.Call, TypeManager.system_type_get_type_from_handle);
+                       ig.Emit (OpCodes.Call, TypeManager.activator_create_instance);
+                       ig.Emit (OpCodes.Unbox_Any, type);
+
+                       return true;
+               }
+
+               //
+               // This DoEmit can be invoked in two contexts:
+               //    * As a mechanism that will leave a value on the stack (new object)
+               //    * As one that wont (init struct)
+               //
+               // You can control whether a value is required on the stack by passing
+               // need_value_on_stack.  The code *might* leave a value on the stack
+               // so it must be popped manually
+               //
+               // If we are dealing with a ValueType, we have a few
+               // situations to deal with:
+               //
+               //    * The target is a ValueType, and we have been provided
+               //      the instance (this is easy, we are being assigned).
+               //
+               //    * The target of New is being passed as an argument,
+               //      to a boxing operation or a function that takes a
+               //      ValueType.
+               //
+               //      In this case, we need to create a temporary variable
+               //      that is the argument of New.
+               //
+               // Returns whether a value is left on the stack
+               //
+               bool DoEmit (EmitContext ec, bool need_value_on_stack)
+               {
+                       bool is_value_type = TypeManager.IsValueType (type);
+                       ILGenerator ig = ec.ig;
+
+                       if (is_value_type){
+                               IMemoryLocation ml;
+
+                               // Allow DoEmit() to be called multiple times.
+                               // We need to create a new LocalTemporary each time since
+                               // you can't share LocalBuilders among ILGeneators.
+                               if (!value_target_set)
+                                       value_target = new LocalTemporary (ec, type);
+
+                               ml = (IMemoryLocation) value_target;
+                               ml.AddressOf (ec, AddressOp.Store);
+                       }
+
+                       if (method != null)
+                               Invocation.EmitArguments (ec, method, Arguments, false, null);
+
+                       if (is_value_type){
+                               if (method == null)
+                                       ig.Emit (OpCodes.Initobj, type);
+                               else 
+                                       ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+                                if (need_value_on_stack){
+                                        value_target.Emit (ec);
+                                        return true;
+                                }
+                                return false;
+                       } else {
+                               ig.Emit (OpCodes.Newobj, (ConstructorInfo) method);
+                               return true;
+                       }
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       if (is_type_parameter)
+                               DoEmitTypeParameter (ec);
+                       else
+                               DoEmit (ec, true);
+               }
+               
+               public override void EmitStatement (EmitContext ec)
+               {
+                       if (is_type_parameter)
+                               throw new InvalidOperationException ();
+
+                       if (DoEmit (ec, false))
+                               ec.ig.Emit (OpCodes.Pop);
+               }
+
+               public void AddressOf (EmitContext ec, AddressOp Mode)
+               {
+                       if (is_type_parameter)
+                               throw new InvalidOperationException ();
+
+                       if (!type.IsValueType){
+                               //
+                               // We throw an exception.  So far, I believe we only need to support
+                               // value types:
+                               // foreach (int j in new StructType ())
+                               // see bug 42390
+                               //
+                               throw new Exception ("AddressOf should not be used for classes");
+                       }
+
+                       if (!value_target_set)
+                               value_target = new LocalTemporary (ec, type);
+                                       
+                       IMemoryLocation ml = (IMemoryLocation) value_target;
+                       ml.AddressOf (ec, AddressOp.Store);
+                       if (method != null)
+                               Invocation.EmitArguments (ec, method, Arguments, false, null);
+
+                       if (method == null)
+                               ec.ig.Emit (OpCodes.Initobj, type);
+                       else 
+                               ec.ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+                       
+                       ((IMemoryLocation) value_target).AddressOf (ec, Mode);
+               }
+       }
+
+       /// <summary>
+       ///   14.5.10.2: Represents an array creation expression.
+       /// </summary>
+       ///
+       /// <remarks>
+       ///   There are two possible scenarios here: one is an array creation
+       ///   expression that specifies the dimensions and optionally the
+       ///   initialization data and the other which does not need dimensions
+       ///   specified but where initialization data is mandatory.
+       /// </remarks>
+       public class ArrayCreation : Expression {
+               Expression requested_base_type;
+               ArrayList initializers;
+
+               //
+               // The list of Argument types.
+               // This is used to construct the `newarray' or constructor signature
+               //
+               ArrayList arguments;
+
+               //
+               // Method used to create the array object.
+               //
+               MethodBase new_method = null;
+               
+               Type array_element_type;
+               Type underlying_type;
+               bool is_one_dimensional = false;
+               bool is_builtin_type = false;
+               bool expect_initializers = false;
+               int num_arguments = 0;
+               int dimensions = 0;
+               string rank;
+
+               ArrayList array_data;
+
+               Hashtable bounds;
+
+               //
+               // The number of array initializers that we can handle
+               // via the InitializeArray method - through EmitStaticInitializers
+               //
+               int num_automatic_initializers;
+
+               const int max_automatic_initializers = 6;
+               
+               public ArrayCreation (Expression requested_base_type, ArrayList exprs, string rank, ArrayList initializers, Location l)
+               {
+                       this.requested_base_type = requested_base_type;
+                       this.initializers = initializers;
+                       this.rank = rank;
+                       loc = l;
+
+                       arguments = new ArrayList ();
+
+                       foreach (Expression e in exprs) {
+                               arguments.Add (new Argument (e, Argument.AType.Expression));
+                               num_arguments++;
+                       }
+               }
+
+               public ArrayCreation (Expression requested_base_type, string rank, ArrayList initializers, Location l)
+               {
+                       this.requested_base_type = requested_base_type;
+                       this.initializers = initializers;
+                       this.rank = rank;
+                       loc = l;
+
+                       //this.rank = rank.Substring (0, rank.LastIndexOf ('['));
+                       //
+                       //string tmp = rank.Substring (rank.LastIndexOf ('['));
+                       //
+                       //dimensions = tmp.Length - 1;
+                       expect_initializers = true;
+               }
+
+               public Expression FormArrayType (Expression base_type, int idx_count, string rank)
+               {
+                       StringBuilder sb = new StringBuilder (rank);
+                       
+                       sb.Append ("[");
+                       for (int i = 1; i < idx_count; i++)
+                               sb.Append (",");
+                       
+                       sb.Append ("]");
+
+                       return new ComposedCast (base_type, sb.ToString (), loc);
+               }
+
+               void Error_IncorrectArrayInitializer ()
+               {
+                       Error (178, "Incorrectly structured array initializer");
+               }
+               
+               public bool CheckIndices (EmitContext ec, ArrayList probe, int idx, bool specified_dims)
+               {
+                       if (specified_dims) { 
+                               Argument a = (Argument) arguments [idx];
+                               
+                               if (!a.Resolve (ec, loc))
+                                       return false;
+                               
+                               if (!(a.Expr is Constant)) {
+                                       Error (150, "A constant value is expected");
+                                       return false;
+                               }
+                               
+                               int value = (int) ((Constant) a.Expr).GetValue ();
+                               
+                               if (value != probe.Count) {
+                                       Error_IncorrectArrayInitializer ();
+                                       return false;
+                               }
+                               
+                               bounds [idx] = value;
+                       }
+
+                       int child_bounds = -1;
+                       foreach (object o in probe) {
+                               if (o is ArrayList) {
+                                       int current_bounds = ((ArrayList) o).Count;
+                                       
+                                       if (child_bounds == -1) 
+                                               child_bounds = current_bounds;
+
+                                       else if (child_bounds != current_bounds){
+                                               Error_IncorrectArrayInitializer ();
+                                               return false;
+                                       }
+                                       if (specified_dims && (idx + 1 >= arguments.Count)){
+                                               Error (623, "Array initializers can only be used in a variable or field initializer, try using the new expression");
+                                               return false;
+                                       }
+                                       
+                                       bool ret = CheckIndices (ec, (ArrayList) o, idx + 1, specified_dims);
+                                       if (!ret)
+                                               return false;
+                               } else {
+                                       if (child_bounds != -1){
+                                               Error_IncorrectArrayInitializer ();
+                                               return false;
+                                       }
+                                       
+                                       Expression tmp = (Expression) o;
+                                       tmp = tmp.Resolve (ec);
+                                       if (tmp == null)
+                                               return false;
+
+                                       // Console.WriteLine ("I got: " + tmp);
+                                       // Handle initialization from vars, fields etc.
+
+                                       Expression conv = Convert.ImplicitConversionRequired (
+                                               ec, tmp, underlying_type, loc);
+                                       
+                                       if (conv == null) 
+                                               return false;
+
+                                       if (conv is StringConstant || conv is DecimalConstant || conv is NullCast) {
+                                               // These are subclasses of Constant that can appear as elements of an
+                                               // array that cannot be statically initialized (with num_automatic_initializers
+                                               // > max_automatic_initializers), so num_automatic_initializers should be left as zero.
+                                               array_data.Add (conv);
+                                       } else if (conv is Constant) {
+                                               // These are the types of Constant that can appear in arrays that can be
+                                               // statically allocated.
+                                               array_data.Add (conv);
+                                               num_automatic_initializers++;
+                                       } else
+                                               array_data.Add (conv);
+                               }
+                       }
+
+                       return true;
+               }
+               
+               public void UpdateIndices (EmitContext ec)
+               {
+                       int i = 0;
+                       for (ArrayList probe = initializers; probe != null;) {
+                               if (probe.Count > 0 && probe [0] is ArrayList) {
+                                       Expression e = new IntConstant (probe.Count);
+                                       arguments.Add (new Argument (e, Argument.AType.Expression));
+
+                                       bounds [i++] =  probe.Count;
+                                       
+                                       probe = (ArrayList) probe [0];
+                                       
+                               } else {
+                                       Expression e = new IntConstant (probe.Count);
+                                       arguments.Add (new Argument (e, Argument.AType.Expression));
+
+                                       bounds [i++] = probe.Count;
+                                       probe = null;
+                               }
+                       }
+
+               }
+               
+               public bool ValidateInitializers (EmitContext ec, Type array_type)
+               {
+                       if (initializers == null) {
+                               if (expect_initializers)
+                                       return false;
+                               else
+                                       return true;
+                       }
+                       
+                       if (underlying_type == null)
+                               return false;
+                       
+                       //
+                       // We use this to store all the date values in the order in which we
+                       // will need to store them in the byte blob later
+                       //
+                       array_data = new ArrayList ();
+                       bounds = new Hashtable ();
+                       
+                       bool ret;
+
+                       if (arguments != null) {
+                               ret = CheckIndices (ec, initializers, 0, true);
+                               return ret;
+                       } else {
+                               arguments = new ArrayList ();
+
+                               ret = CheckIndices (ec, initializers, 0, false);
+                               
+                               if (!ret)
+                                       return false;
+                               
+                               UpdateIndices (ec);
+                               
+                               if (arguments.Count != dimensions) {
+                                       Error_IncorrectArrayInitializer ();
+                                       return false;
+                               }
+
+                               return ret;
+                       }
+               }
+
+               //
+               // Converts `source' to an int, uint, long or ulong.
+               //
+               Expression ExpressionToArrayArgument (EmitContext ec, Expression source)
+               {
+                       Expression target;
+                       
+                       bool old_checked = ec.CheckState;
+                       ec.CheckState = true;
+                       
+                       target = Convert.ImplicitConversion (ec, source, TypeManager.int32_type, loc);
+                       if (target == null){
+                               target = Convert.ImplicitConversion (ec, source, TypeManager.uint32_type, loc);
+                               if (target == null){
+                                       target = Convert.ImplicitConversion (ec, source, TypeManager.int64_type, loc);
+                                       if (target == null){
+                                               target = Convert.ImplicitConversion (ec, source, TypeManager.uint64_type, loc);
+                                               if (target == null)
+                                                       Convert.Error_CannotImplicitConversion (loc, source.Type, TypeManager.int32_type);
+                                       }
+                               }
+                       } 
+                       ec.CheckState = old_checked;
+
+                       //
+                       // Only positive constants are allowed at compile time
+                       //
+                       if (target is Constant){
+                               if (target is IntConstant){
+                                       if (((IntConstant) target).Value < 0){
+                                               Expression.Error_NegativeArrayIndex (loc);
+                                               return null;
+                                       }
+                               }
+
+                               if (target is LongConstant){
+                                       if (((LongConstant) target).Value < 0){
+                                               Expression.Error_NegativeArrayIndex (loc);
+                                               return null;
+                                       }
+                               }
+                               
+                       }
+
+                       return target;
+               }
+
+               //
+               // Creates the type of the array
+               //
+               bool LookupType (EmitContext ec)
+               {
+                       StringBuilder array_qualifier = new StringBuilder (rank);
+
+                       //
+                       // `In the first form allocates an array instace of the type that results
+                       // from deleting each of the individual expression from the expression list'
+                       //
+                       if (num_arguments > 0) {
+                               array_qualifier.Append ("[");
+                               for (int i = num_arguments-1; i > 0; i--)
+                                       array_qualifier.Append (",");
+                               array_qualifier.Append ("]");                           
+                       }
+
+                       //
+                       // Lookup the type
+                       //
+                       TypeExpr array_type_expr;
+                       array_type_expr = new ComposedCast (requested_base_type, array_qualifier.ToString (), loc);
+                       array_type_expr = array_type_expr.ResolveAsTypeTerminal (ec);
+                       if (array_type_expr == null)
+                               return false;
+
+                       type = array_type_expr.Type;
+
+                       if (!type.IsArray) {
+                               Error (622, "Can only use array initializer expressions to assign to array types. Try using a new expression instead.");
+                               return false;
+                       }
+                       underlying_type = TypeManager.GetElementType (type);
+                       dimensions = type.GetArrayRank ();
+
+                       return true;
+               }
+               
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       int arg_count;
+
+                       if (!LookupType (ec))
+                               return null;
+                       
+                       //
+                       // First step is to validate the initializers and fill
+                       // in any missing bits
+                       //
+                       if (!ValidateInitializers (ec, type))
+                               return null;
+
+                       if (arguments == null)
+                               arg_count = 0;
+                       else {
+                               arg_count = arguments.Count;
+                               foreach (Argument a in arguments){
+                                       if (!a.Resolve (ec, loc))
+                                               return null;
+
+                                       Expression real_arg = ExpressionToArrayArgument (ec, a.Expr, loc);
+                                       if (real_arg == null)
+                                               return null;
+
+                                       a.Expr = real_arg;
+                               }
+                       }
+                       
+                       array_element_type = TypeManager.GetElementType (type);
+
+                       if (array_element_type.IsAbstract && array_element_type.IsSealed) {
+                               Report.Error (719, loc, "'{0}': array elements cannot be of static type", TypeManager.CSharpName (array_element_type));
+                               return null;
+                       }
+
+                       if (arg_count == 1) {
+                               is_one_dimensional = true;
+                               eclass = ExprClass.Value;
+                               return this;
+                       }
+
+                       is_builtin_type = TypeManager.IsBuiltinType (type);
+
+                       if (is_builtin_type) {
+                               Expression ml;
+                               
+                               ml = MemberLookup (ec, type, ".ctor", MemberTypes.Constructor,
+                                                  AllBindingFlags, loc);
+                               
+                               if (!(ml is MethodGroupExpr)) {
+                                       ml.Error_UnexpectedKind ("method group", loc);
+                                       return null;
+                               }
+                               
+                               if (ml == null) {
+                                       Error (-6, "New invocation: Can not find a constructor for " +
+                                                     "this argument list");
+                                       return null;
+                               }
+                               
+                               new_method = Invocation.OverloadResolve (
+                                       ec, (MethodGroupExpr) ml, arguments, false, loc);
+
+                               if (new_method == null) {
+                                       Error (-6, "New invocation: Can not find a constructor for " +
+                                                     "this argument list");
+                                       return null;
+                               }
+                               
+                               eclass = ExprClass.Value;
+                               return this;
+                       } else {
+                               ModuleBuilder mb = CodeGen.Module.Builder;
+                               ArrayList args = new ArrayList ();
+                               
+                               if (arguments != null) {
+                                       for (int i = 0; i < arg_count; i++)
+                                               args.Add (TypeManager.int32_type);
+                               }
+                               
+                               Type [] arg_types = null;
+
+                               if (args.Count > 0)
+                                       arg_types = new Type [args.Count];
+                               
+                               args.CopyTo (arg_types, 0);
+                               
+                               new_method = mb.GetArrayMethod (type, ".ctor", CallingConventions.HasThis, null,
+                                                           arg_types);
+
+                               if (new_method == null) {
+                                       Error (-6, "New invocation: Can not find a constructor for " +
+                                                     "this argument list");
+                                       return null;
+                               }
+                               
+                               eclass = ExprClass.Value;
+                               return this;
+                       }
+               }
+
+               public static byte [] MakeByteBlob (ArrayList array_data, Type underlying_type, Location loc)
+               {
+                       int factor;
+                       byte [] data;
+                       byte [] element;
+                       int count = array_data.Count;
+
+                       if (underlying_type.IsEnum)
+                               underlying_type = TypeManager.EnumToUnderlying (underlying_type);
+                       
+                       factor = GetTypeSize (underlying_type);
+                       if (factor == 0)
+                               throw new Exception ("unrecognized type in MakeByteBlob: " + underlying_type);
+
+                       data = new byte [(count * factor + 4) & ~3];
+                       int idx = 0;
+                       
+                       for (int i = 0; i < count; ++i) {
+                               object v = array_data [i];
+
+                               if (v is EnumConstant)
+                                       v = ((EnumConstant) v).Child;
+                               
+                               if (v is Constant && !(v is StringConstant))
+                                       v = ((Constant) v).GetValue ();
+                               else {
+                                       idx += factor;
+                                       continue;
+                               }
+                               
+                               if (underlying_type == TypeManager.int64_type){
+                                       if (!(v is Expression)){
+                                               long val = (long) v;
+                                               
+                                               for (int j = 0; j < factor; ++j) {
+                                                       data [idx + j] = (byte) (val & 0xFF);
+                                                       val = (val >> 8);
+                                               }
+                                       }
+                               } else if (underlying_type == TypeManager.uint64_type){
+                                       if (!(v is Expression)){
+                                               ulong val = (ulong) v;
+
+                                               for (int j = 0; j < factor; ++j) {
+                                                       data [idx + j] = (byte) (val & 0xFF);
+                                                       val = (val >> 8);
+                                               }
+                                       }
+                               } else if (underlying_type == TypeManager.float_type) {
+                                       if (!(v is Expression)){
+                                               element = BitConverter.GetBytes ((float) v);
+                                                       
+                                               for (int j = 0; j < factor; ++j)
+                                                       data [idx + j] = element [j];
+                                       }
+                               } else if (underlying_type == TypeManager.double_type) {
+                                       if (!(v is Expression)){
+                                               element = BitConverter.GetBytes ((double) v);
+
+                                               for (int j = 0; j < factor; ++j)
+                                                       data [idx + j] = element [j];
+                                       }
+                               } else if (underlying_type == TypeManager.char_type){
+                                       if (!(v is Expression)){
+                                               int val = (int) ((char) v);
+                                               
+                                               data [idx] = (byte) (val & 0xff);
+                                               data [idx+1] = (byte) (val >> 8);
+                                       }
+                               } else if (underlying_type == TypeManager.short_type){
+                                       if (!(v is Expression)){
+                                               int val = (int) ((short) v);
+                                       
+                                               data [idx] = (byte) (val & 0xff);
+                                               data [idx+1] = (byte) (val >> 8);
+                                       }
+                               } else if (underlying_type == TypeManager.ushort_type){
+                                       if (!(v is Expression)){
+                                               int val = (int) ((ushort) v);
+                                       
+                                               data [idx] = (byte) (val & 0xff);
+                                               data [idx+1] = (byte) (val >> 8);
+                                       }
+                               } else if (underlying_type == TypeManager.int32_type) {
+                                       if (!(v is Expression)){
+                                               int val = (int) v;
+                                       
+                                               data [idx]   = (byte) (val & 0xff);
+                                               data [idx+1] = (byte) ((val >> 8) & 0xff);
+                                               data [idx+2] = (byte) ((val >> 16) & 0xff);
+                                               data [idx+3] = (byte) (val >> 24);
+                                       }
+                               } else if (underlying_type == TypeManager.uint32_type) {
+                                       if (!(v is Expression)){
+                                               uint val = (uint) v;
+                                       
+                                               data [idx]   = (byte) (val & 0xff);
+                                               data [idx+1] = (byte) ((val >> 8) & 0xff);
+                                               data [idx+2] = (byte) ((val >> 16) & 0xff);
+                                               data [idx+3] = (byte) (val >> 24);
+                                       }
+                               } else if (underlying_type == TypeManager.sbyte_type) {
+                                       if (!(v is Expression)){
+                                               sbyte val = (sbyte) v;
+                                               data [idx] = (byte) val;
+                                       }
+                               } else if (underlying_type == TypeManager.byte_type) {
+                                       if (!(v is Expression)){
+                                               byte val = (byte) v;
+                                               data [idx] = (byte) val;
+                                       }
+                               } else if (underlying_type == TypeManager.bool_type) {
+                                       if (!(v is Expression)){
+                                               bool val = (bool) v;
+                                               data [idx] = (byte) (val ? 1 : 0);
+                                       }
+                               } else if (underlying_type == TypeManager.decimal_type){
+                                       if (!(v is Expression)){
+                                               int [] bits = Decimal.GetBits ((decimal) v);
+                                               int p = idx;
+
+                                               // FIXME: For some reason, this doesn't work on the MS runtime.
+                                               int [] nbits = new int [4];
+                                               nbits [0] = bits [3];
+                                               nbits [1] = bits [2];
+                                               nbits [2] = bits [0];
+                                               nbits [3] = bits [1];
+                                               
+                                               for (int j = 0; j < 4; j++){
+                                                       data [p++] = (byte) (nbits [j] & 0xff);
+                                                       data [p++] = (byte) ((nbits [j] >> 8) & 0xff);
+                                                       data [p++] = (byte) ((nbits [j] >> 16) & 0xff);
+                                                       data [p++] = (byte) (nbits [j] >> 24);
+                                               }
+                                       }
+                               } else
+                                       throw new Exception ("Unrecognized type in MakeByteBlob: " + underlying_type);
+
+                                idx += factor;
+                       }
+
+                       return data;
+               }
+
+               //
+               // Emits the initializers for the array
+               //
+               void EmitStaticInitializers (EmitContext ec)
+               {
+                       //
+                       // First, the static data
+                       //
+                       FieldBuilder fb;
+                       ILGenerator ig = ec.ig;
+                       
+                       byte [] data = MakeByteBlob (array_data, underlying_type, loc);
+
+                       fb = RootContext.MakeStaticData (data);
+
+                       ig.Emit (OpCodes.Dup);
+                       ig.Emit (OpCodes.Ldtoken, fb);
+                       ig.Emit (OpCodes.Call,
+                                TypeManager.void_initializearray_array_fieldhandle);
+               }
+
+               //
+               // Emits pieces of the array that can not be computed at compile
+               // time (variables and string locations).
+               //
+               // This always expect the top value on the stack to be the array
+               //
+               void EmitDynamicInitializers (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       int dims = bounds.Count;
+                       int [] current_pos = new int [dims];
+                       int top = array_data.Count;
+
+                       MethodInfo set = null;
+
+                       if (dims != 1){
+                               Type [] args;
+                               ModuleBuilder mb = null;
+                               mb = CodeGen.Module.Builder;
+                               args = new Type [dims + 1];
+
+                               int j;
+                               for (j = 0; j < dims; j++)
+                                       args [j] = TypeManager.int32_type;
+
+                               args [j] = array_element_type;
+                               
+                               set = mb.GetArrayMethod (
+                                       type, "Set",
+                                       CallingConventions.HasThis | CallingConventions.Standard,
+                                       TypeManager.void_type, args);
+                       }
+                       
+                       for (int i = 0; i < top; i++){
+
+                               Expression e = null;
+
+                               if (array_data [i] is Expression)
+                                       e = (Expression) array_data [i];
+
+                               if (e != null) {
+                                       //
+                                       // Basically we do this for string literals and
+                                       // other non-literal expressions
+                                       //
+                                       if (e is EnumConstant){
+                                               e = ((EnumConstant) e).Child;
+                                       }
+                                       
+                                       if (e is StringConstant || e is DecimalConstant || !(e is Constant) ||
+                                           num_automatic_initializers <= max_automatic_initializers) {
+                                               Type etype = e.Type;
+                                               
+                                               ig.Emit (OpCodes.Dup);
+
+                                               for (int idx = 0; idx < dims; idx++) 
+                                                       IntConstant.EmitInt (ig, current_pos [idx]);
+
+                                               //
+                                               // If we are dealing with a struct, get the
+                                               // address of it, so we can store it.
+                                               //
+                                               if ((dims == 1) && 
+                                                   etype.IsSubclassOf (TypeManager.value_type) &&
+                                                   (!TypeManager.IsBuiltinOrEnum (etype) ||
+                                                    etype == TypeManager.decimal_type)) {
+                                                       if (e is New){
+                                                               New n = (New) e;
+
+                                                               //
+                                                               // Let new know that we are providing
+                                                               // the address where to store the results
+                                                               //
+                                                               n.DisableTemporaryValueType ();
+                                                       }
+
+                                                       ig.Emit (OpCodes.Ldelema, etype);
+                                               }
+
+                                               e.Emit (ec);
+
+                                               if (dims == 1) {
+                                                       bool is_stobj, has_type_arg;
+                                                       OpCode op = ArrayAccess.GetStoreOpcode (
+                                                               etype, out is_stobj,
+                                                               out has_type_arg);
+                                                       if (is_stobj)
+                                                               ig.Emit (OpCodes.Stobj, etype);
+                                                       else if (has_type_arg)
+                                                               ig.Emit (op, etype);
+                                                       else
+                                                               ig.Emit (op);
+                                               } else 
+                                                        ig.Emit (OpCodes.Call, set);
+                                       }
+                               }
+                               
+                               //
+                               // Advance counter
+                               //
+                               for (int j = dims - 1; j >= 0; j--){
+                                       current_pos [j]++;
+                                       if (current_pos [j] < (int) bounds [j])
+                                               break;
+                                       current_pos [j] = 0;
+                               }
+                       }
+               }
+
+               void EmitArrayArguments (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       foreach (Argument a in arguments) {
+                               Type atype = a.Type;
+                               a.Emit (ec);
+
+                               if (atype == TypeManager.uint64_type)
+                                       ig.Emit (OpCodes.Conv_Ovf_U4);
+                               else if (atype == TypeManager.int64_type)
+                                       ig.Emit (OpCodes.Conv_Ovf_I4);
+                       }
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       EmitArrayArguments (ec);
+                       if (is_one_dimensional)
+                               ig.Emit (OpCodes.Newarr, array_element_type);
+                       else {
+                               if (is_builtin_type) 
+                                       ig.Emit (OpCodes.Newobj, (ConstructorInfo) new_method);
+                               else 
+                                       ig.Emit (OpCodes.Newobj, (MethodInfo) new_method);
+                       }
+                       
+                       if (initializers != null){
+                               //
+                               // FIXME: Set this variable correctly.
+                               // 
+                               bool dynamic_initializers = true;
+
+                               // This will never be true for array types that cannot be statically
+                               // initialized. num_automatic_initializers will always be zero.  See
+                               // CheckIndices.
+                                       if (num_automatic_initializers > max_automatic_initializers)
+                                               EmitStaticInitializers (ec);
+                               
+                               if (dynamic_initializers)
+                                       EmitDynamicInitializers (ec);
+                       }
+               }
+               
+               public object EncodeAsAttribute ()
+               {
+                       if (!is_one_dimensional){
+                               Report.Error (-211, Location, "attribute can not encode multi-dimensional arrays");
+                               return null;
+                       }
+
+                       if (array_data == null){
+                               Report.Error (-212, Location, "array should be initialized when passing it to an attribute");
+                               return null;
+                       }
+                       
+                       object [] ret = new object [array_data.Count];
+                       int i = 0;
+                       foreach (Expression e in array_data){
+                               object v;
+                               
+                               if (e is NullLiteral)
+                                       v = null;
+                               else {
+                                       if (!Attribute.GetAttributeArgumentExpression (e, Location, array_element_type, out v))
+                                               return null;
+                               }
+                               ret [i++] = v;
+                       }
+                       return ret;
+               }
+       }
+       
+       /// <summary>
+       ///   Represents the `this' construct
+       /// </summary>
+       public class This : Expression, IAssignMethod, IMemoryLocation, IVariable {
+
+               Block block;
+               VariableInfo variable_info;
+               
+               public This (Block block, Location loc)
+               {
+                       this.loc = loc;
+                       this.block = block;
+               }
+
+               public This (Location loc)
+               {
+                       this.loc = loc;
+               }
+
+               public VariableInfo VariableInfo {
+                       get { return variable_info; }
+               }
+
+               public bool VerifyFixed (bool is_expression)
+               {
+                       if ((variable_info == null) || (variable_info.LocalInfo == null))
+                               return false;
+                       else
+                               return variable_info.LocalInfo.IsFixed;
+               }
+
+               public bool ResolveBase (EmitContext ec)
+               {
+                       eclass = ExprClass.Variable;
+
+                       if (ec.TypeContainer.CurrentType != null)
+                               type = ec.TypeContainer.CurrentType;
+                       else
+                               type = ec.ContainerType;
+
+                       if (ec.IsStatic) {
+                               Error (26, "Keyword this not valid in static code");
+                               return false;
+                       }
+
+                       if ((block != null) && (block.ThisVariable != null))
+                               variable_info = block.ThisVariable.VariableInfo;
+
+                       return true;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if (!ResolveBase (ec))
+                               return null;
+
+                       if ((variable_info != null) && !variable_info.IsAssigned (ec)) {
+                               Error (188, "The this object cannot be used before all " +
+                                      "of its fields are assigned to");
+                               variable_info.SetAssigned (ec);
+                               return this;
+                       }
+
+                       if (ec.IsFieldInitializer) {
+                               Error (27, "Keyword `this' can't be used outside a constructor, " +
+                                      "a method or a property.");
+                               return null;
+                       }
+
+                       return this;
+               }
+
+               override public Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       if (!ResolveBase (ec))
+                               return null;
+
+                       if (variable_info != null)
+                               variable_info.SetAssigned (ec);
+                       
+                       if (ec.TypeContainer is Class){
+                               Error (1604, "Cannot assign to `this'");
+                               return null;
+                       }
+
+                       return this;
+               }
+
+               public void Emit (EmitContext ec, bool leave_copy)
+               {
+                       Emit (ec);
+                       if (leave_copy)
+                               ec.ig.Emit (OpCodes.Dup);
+               }
+               
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       if (ec.TypeContainer is Struct){
+                               ec.EmitThis ();
+                               source.Emit (ec);
+                               if (leave_copy)
+                                       ec.ig.Emit (OpCodes.Dup);
+                               ig.Emit (OpCodes.Stobj, type);
+                       } else {
+                               throw new Exception ("how did you get here");
+                       }
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       ec.EmitThis ();
+                       if (ec.TypeContainer is Struct)
+                               ig.Emit (OpCodes.Ldobj, type);
+               }
+
+               public void AddressOf (EmitContext ec, AddressOp mode)
+               {
+                       ec.EmitThis ();
+
+                       // FIMXE
+                       // FIGURE OUT WHY LDARG_S does not work
+                       //
+                       // consider: struct X { int val; int P { set { val = value; }}}
+                       //
+                       // Yes, this looks very bad. Look at `NOTAS' for
+                       // an explanation.
+                       // ec.ig.Emit (OpCodes.Ldarga_S, (byte) 0);
+               }
+       }
+
+       /// <summary>
+       ///   Represents the `__arglist' construct
+       /// </summary>
+       public class ArglistAccess : Expression
+       {
+               public ArglistAccess (Location loc)
+               {
+                       this.loc = loc;
+               }
+
+               public bool ResolveBase (EmitContext ec)
+               {
+                       eclass = ExprClass.Variable;
+                       type = TypeManager.runtime_argument_handle_type;
+                       return true;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if (!ResolveBase (ec))
+                               return null;
+
+                       if (ec.IsFieldInitializer || !ec.CurrentBlock.HasVarargs) {
+                               Error (190, "The __arglist construct is valid only within " +
+                                      "a variable argument method.");
+                               return null;
+                       }
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ec.ig.Emit (OpCodes.Arglist);
+               }
+       }
+
+       /// <summary>
+       ///   Represents the `__arglist (....)' construct
+       /// </summary>
+       public class Arglist : Expression
+       {
+               public readonly Argument[] Arguments;
+
+               public Arglist (Argument[] args, Location l)
+               {
+                       Arguments = args;
+                       loc = l;
+               }
+
+               public Type[] ArgumentTypes {
+                       get {
+                               Type[] retval = new Type [Arguments.Length];
+                               for (int i = 0; i < Arguments.Length; i++)
+                                       retval [i] = Arguments [i].Type;
+                               return retval;
+                       }
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       eclass = ExprClass.Variable;
+                       type = TypeManager.runtime_argument_handle_type;
+
+                       foreach (Argument arg in Arguments) {
+                               if (!arg.Resolve (ec, loc))
+                                       return null;
+                       }
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       foreach (Argument arg in Arguments)
+                               arg.Emit (ec);
+               }
+       }
+
+       //
+       // This produces the value that renders an instance, used by the iterators code
+       //
+       public class ProxyInstance : Expression, IMemoryLocation  {
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       eclass = ExprClass.Variable;
+                       type = ec.ContainerType;
+                       return this;
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       ec.ig.Emit (OpCodes.Ldarg_0);
+
+               }
+               
+               public void AddressOf (EmitContext ec, AddressOp mode)
+               {
+                       ec.ig.Emit (OpCodes.Ldarg_0);
+               }
+       }
+
+       /// <summary>
+       ///   Implements the typeof operator
+       /// </summary>
+       public class TypeOf : Expression {
+               public Expression QueriedType;
+               protected Type typearg;
+               
+               public TypeOf (Expression queried_type, Location l)
+               {
+                       QueriedType = queried_type;
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       TypeExpr texpr = QueriedType.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return null;
+
+                       typearg = texpr.Type;
+
+                       if (typearg == TypeManager.void_type) {
+                               Error (673, "System.Void cannot be used from C# - " +
+                                      "use typeof (void) to get the void type object");
+                               return null;
+                       }
+
+                       if (typearg.IsPointer && !ec.InUnsafe){
+                               UnsafeError (loc);
+                               return null;
+                       }
+                       CheckObsoleteAttribute (typearg);
+
+                       type = TypeManager.type_type;
+                       eclass = ExprClass.Type;
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ec.ig.Emit (OpCodes.Ldtoken, typearg);
+                       ec.ig.Emit (OpCodes.Call, TypeManager.system_type_get_type_from_handle);
+               }
+
+               public Type TypeArg { 
+                       get { return typearg; }
+               }
+       }
+
+       /// <summary>
+       ///   Implements the `typeof (void)' operator
+       /// </summary>
+       public class TypeOfVoid : TypeOf {
+               public TypeOfVoid (Location l) : base (null, l)
+               {
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.type_type;
+                       typearg = TypeManager.void_type;
+                       eclass = ExprClass.Type;
+                       return this;
+               }
+       }
+
+       /// <summary>
+       ///   Implements the sizeof expression
+       /// </summary>
+       public class SizeOf : Expression {
+               public Expression QueriedType;
+               Type type_queried;
+               
+               public SizeOf (Expression queried_type, Location l)
+               {
+                       this.QueriedType = queried_type;
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if (!ec.InUnsafe) {
+                               Report.Error (
+                                       233, loc, "Sizeof may only be used in an unsafe context " +
+                                       "(consider using System.Runtime.InteropServices.Marshal.SizeOf");
+                               return null;
+                       }
+                               
+                       TypeExpr texpr = QueriedType.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return null;
+
+                       if (texpr is TypeParameterExpr){
+                               ((TypeParameterExpr)texpr).Error_CannotUseAsUnmanagedType (loc);
+                               return null;
+                       }
+
+                       type_queried = texpr.Type;
+
+                       CheckObsoleteAttribute (type_queried);
+
+                       if (!TypeManager.IsUnmanagedType (type_queried)){
+                               Report.Error (208, loc, "Cannot take the size of an unmanaged type (" + TypeManager.CSharpName (type_queried) + ")");
+                               return null;
+                       }
+                       
+                       type = TypeManager.int32_type;
+                       eclass = ExprClass.Value;
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       int size = GetTypeSize (type_queried);
+
+                       if (size == 0)
+                               ec.ig.Emit (OpCodes.Sizeof, type_queried);
+                       else
+                               IntConstant.EmitInt (ec.ig, size);
+               }
+       }
+
+       /// <summary>
+       ///   Implements the member access expression
+       /// </summary>
+       public class MemberAccess : Expression {
+               public string Identifier;
+               protected Expression expr;
+               protected TypeArguments args;
+               
+               public MemberAccess (Expression expr, string id, Location l)
+               {
+                       this.expr = expr;
+                       Identifier = id;
+                       loc = l;
+               }
+
+               public MemberAccess (Expression expr, string id, TypeArguments args,
+                                    Location l)
+                       : this (expr, id, l)
+               {
+                       this.args = args;
+               }
+
+               public Expression Expr {
+                       get {
+                               return expr;
+                       }
+               }
+
+               public static void error176 (Location loc, string name)
+               {
+                       Report.Error (176, loc, "Static member `" +
+                                     name + "' cannot be accessed " +
+                                     "with an instance reference, qualify with a " +
+                                     "type name instead");
+               }
+
+               public static bool IdenticalNameAndTypeName (EmitContext ec, Expression left_original, Expression left, Location loc)
+               {
+                       SimpleName sn = left_original as SimpleName;
+                       if (sn == null || left == null || left.Type.Name != sn.Name)
+                               return false;
+
+                       return RootContext.LookupType (ec.DeclSpace, sn.Name, true, loc) != null;
+               }
+               
+               // TODO: possible optimalization
+               // Cache resolved constant result in FieldBuilder <-> expresion map
+               public static Expression ResolveMemberAccess (EmitContext ec, Expression member_lookup,
+                                                             Expression left, Location loc,
+                                                             Expression left_original)
+               {
+                       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.
+                       if (left == null) {
+                               left_is_type = ec.IsStatic || ec.IsFieldInitializer;
+                               left_is_explicit = false;
+
+                               // Implicitly default to `this' unless we're static.
+                               if (!ec.IsStatic && !ec.IsFieldInitializer && !ec.InEnumContext)
+                                       left = ec.GetThis (loc);
+                       } else {
+                               left_is_type = left is TypeExpr;
+                               left_is_explicit = true;
+                       }
+
+                       if (member_lookup is FieldExpr){
+                               FieldExpr fe = (FieldExpr) member_lookup;
+                               FieldInfo fi = fe.FieldInfo.Mono_GetGenericFieldDefinition ();
+                               Type decl_type = fi.DeclaringType;
+
+                               bool is_emitted = fi is FieldBuilder;
+                               Type t = fi.FieldType;
+
+                               if (is_emitted) {
+                                       Const c = TypeManager.LookupConstant ((FieldBuilder) fi);
+                                       
+                                       if (c != null) {
+                                               object o;
+                                               if (!c.LookupConstantValue (out o))
+                                                       return null;
+
+                                               object real_value = ((Constant) c.Expr).GetValue ();
+
+                                               return Constantify (real_value, t);
+                                       }
+                               }
+
+                               // IsInitOnly is because of MS compatibility, I don't know why but they emit decimal constant as InitOnly
+                               if (fi.IsInitOnly && !is_emitted && t == 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) {
+                                       object o;
+
+                                       if (is_emitted)
+                                               o = TypeManager.GetValue ((FieldBuilder) fi);
+                                       else
+                                               o = fi.GetValue (fi);
+                                       
+                                       if (decl_type.IsSubclassOf (TypeManager.enum_type)) {
+                                               if (left_is_explicit && !left_is_type &&
+                                                   !IdenticalNameAndTypeName (ec, left_original, member_lookup, loc)) {
+                                                       error176 (loc, fe.FieldInfo.Name);
+                                                       return null;
+                                               }                                       
+                                               
+                                               Expression enum_member = MemberLookup (
+                                                       ec, decl_type, "value__", MemberTypes.Field,
+                                                       AllBindingFlags, loc); 
+
+                                               Enum en = TypeManager.LookupEnum (decl_type);
+
+                                               Constant c;
+                                               if (en != null)
+                                                       c = Constantify (o, en.UnderlyingType);
+                                               else 
+                                                       c = Constantify (o, enum_member.Type);
+                                               
+                                               return new EnumConstant (c, decl_type);
+                                       }
+                                       
+                                       Expression exp = Constantify (o, t);
+
+                                       if (left_is_explicit && !left_is_type) {
+                                               error176 (loc, fe.FieldInfo.Name);
+                                               return null;
+                                       }
+                                       
+                                       return exp;
+                               }
+
+                               if (t.IsPointer && !ec.InUnsafe){
+                                       UnsafeError (loc);
+                                       return null;
+                               }
+                       }
+
+                       if (member_lookup is EventExpr) {
+                               EventExpr ee = (EventExpr) member_lookup;
+                               
+                               //
+                               // If the event is local to this class, we transform ourselves into
+                               // a FieldExpr
+                               //
+
+                               if (ee.EventInfo.DeclaringType == ec.ContainerType ||
+                                   TypeManager.IsNestedChildOf(ec.ContainerType, ee.EventInfo.DeclaringType)) {
+                                       MemberInfo mi = GetFieldFromEvent (ee);
+
+                                       if (mi == null) {
+                                               //
+                                               // If this happens, then we have an event with its own
+                                               // accessors and private field etc so there's no need
+                                               // to transform ourselves.
+                                               //
+                                               ee.InstanceExpression = left;
+                                               return ee;
+                                       }
+
+                                       Expression ml = ExprClassFromMemberInfo (ec, mi, loc);
+                                       
+                                       if (ml == null) {
+                                               Report.Error (-200, loc, "Internal error!!");
+                                               return null;
+                                       }
+
+                                       if (!left_is_explicit)
+                                               left = null;
+                                       
+                                       ee.InstanceExpression = left;
+
+                                       return ResolveMemberAccess (ec, ml, left, loc, left_original);
+                               }
+                       }
+
+                       if (member_lookup is IMemberExpr) {
+                               IMemberExpr me = (IMemberExpr) member_lookup;
+                               MethodGroupExpr mg = me as MethodGroupExpr;
+
+                               if (left_is_type){
+                                       if ((mg != null) && left_is_explicit && left.Type.IsInterface)
+                                               mg.IsExplicitImpl = left_is_explicit;
+
+                                       if (!me.IsStatic){
+                                               if ((ec.IsFieldInitializer || ec.IsStatic) &&
+                                                   IdenticalNameAndTypeName (ec, left_original, member_lookup, loc))
+                                                       return member_lookup;
+
+                                               SimpleName.Error_ObjectRefRequired (ec, loc, me.Name);
+                                               return null;
+                                       }
+
+                               } else {
+                                       if (!me.IsInstance){
+                                               if (IdenticalNameAndTypeName (ec, left_original, left, loc))
+                                                       return member_lookup;
+
+                                               if (left_is_explicit) {
+                                                       error176 (loc, me.Name);
+                                                       return null;
+                                               }
+                                       }
+
+                                       //
+                                       // Since we can not check for instance objects in SimpleName,
+                                       // becaue of the rule that allows types and variables to share
+                                       // the name (as long as they can be de-ambiguated later, see 
+                                       // IdenticalNameAndTypeName), we have to check whether left 
+                                       // is an instance variable in a static context
+                                       //
+                                       // However, if the left-hand value is explicitly given, then
+                                       // it is already our instance expression, so we aren't in
+                                       // static context.
+                                       //
+
+                                       if (ec.IsStatic && !left_is_explicit && left is IMemberExpr){
+                                               IMemberExpr mexp = (IMemberExpr) left;
+
+                                               if (!mexp.IsStatic){
+                                                       SimpleName.Error_ObjectRefRequired (ec, loc, mexp.Name);
+                                                       return null;
+                                               }
+                                       }
+
+                                       if ((mg != null) && IdenticalNameAndTypeName (ec, left_original, left, loc))
+                                               mg.IdenticalTypeName = true;
+
+                                       me.InstanceExpression = left;
+                               }
+
+                               return member_lookup;
+                       }
+
+                       Console.WriteLine ("Left is: " + left);
+                       Report.Error (-100, loc, "Support for [" + member_lookup + "] is not present yet");
+                       Environment.Exit (1);
+                       return null;
+               }
+               
+               public virtual Expression DoResolve (EmitContext ec, Expression right_side,
+                                                    ResolveFlags flags)
+               {
+                       if (type != null)
+                               throw new Exception ();
+
+                       //
+                       // Resolve the expression with flow analysis turned off, we'll do the definite
+                       // assignment checks later.  This is because we don't know yet what the expression
+                       // will resolve to - it may resolve to a FieldExpr and in this case we must do the
+                       // definite assignment check on the actual field and not on the whole struct.
+                       //
+
+                       Expression original = expr;
+                       expr = expr.Resolve (ec, flags | ResolveFlags.Intermediate | ResolveFlags.DisableFlowAnalysis);
+                       if (expr == null)
+                               return null;
+
+                       if (expr is SimpleName){
+                               SimpleName child_expr = (SimpleName) expr;
+                               string fqname = DeclSpace.MakeFQN (child_expr.Name, Identifier);
+
+                               Expression new_expr;
+                               if (args != null)
+                                       new_expr = new ConstructedType (fqname, args, loc);
+                               else
+                                       new_expr = new SimpleName (fqname, loc);
+
+                               return new_expr.Resolve (ec, flags);
+                       }
+                                       
+                       //
+                       // TODO: I mailed Ravi about this, and apparently we can get rid
+                       // of this and put it in the right place.
+                       // 
+                       // Handle enums here when they are in transit.
+                       // Note that we cannot afford to hit MemberLookup in this case because
+                       // it will fail to find any members at all
+                       //
+
+                       Type expr_type;
+                       if (expr is TypeExpr){
+                               expr_type = expr.Type;
+
+                               if (!ec.DeclSpace.CheckAccessLevel (expr_type)){
+                                       Report.Error (122, loc, "'{0}' is inaccessible due to its protection level", expr_type);
+                                       return null;
+                               }
+
+                               if (expr_type == TypeManager.enum_type || expr_type.IsSubclassOf (TypeManager.enum_type)){
+                                       Enum en = TypeManager.LookupEnum (expr_type);
+
+                                       if (en != null) {
+                                               object value = en.LookupEnumValue (ec, Identifier, loc);
+                                               
+                                               if (value != null){
+                                                       MemberCore mc = en.GetDefinition (Identifier);
+                                                       ObsoleteAttribute oa = mc.GetObsoleteAttribute (en);
+                                                       if (oa != null) {
+                                                               AttributeTester.Report_ObsoleteMessage (oa, mc.GetSignatureForError (), Location);
+                                                       }
+                                                       oa = en.GetObsoleteAttribute (en);
+                                                       if (oa != null) {
+                                                               AttributeTester.Report_ObsoleteMessage (oa, en.GetSignatureForError (), Location);
+                                                       }
+
+                                                       Constant c = Constantify (value, en.UnderlyingType);
+                                                       return new EnumConstant (c, expr_type);
+                                               }
+                                       } else {
+                                               CheckObsoleteAttribute (expr_type);
+
+                                               FieldInfo fi = expr_type.GetField (Identifier);
+                                               if (fi != null) {
+                                                       ObsoleteAttribute oa = AttributeTester.GetMemberObsoleteAttribute (fi);
+                                                       if (oa != null)
+                                                               AttributeTester.Report_ObsoleteMessage (oa, TypeManager.GetFullNameSignature (fi), Location);
+                                               }
+                                       }
+                               }
+                       } else
+                               expr_type = expr.Type;
+                       
+                       if (expr_type.IsPointer){
+                               Error (23, "The `.' operator can not be applied to pointer operands (" +
+                                      TypeManager.CSharpName (expr_type) + ")");
+                               return null;
+                       }
+
+                       int errors = Report.Errors;
+
+                       Expression member_lookup;
+                       member_lookup = MemberLookup (
+                               ec, expr_type, expr_type, Identifier, loc);
+                       if ((member_lookup == null) && (args != null)) {
+                               string lookup_id = MemberName.MakeName (Identifier, args);
+                               member_lookup = MemberLookup (
+                                       ec, expr_type, expr_type, lookup_id, loc);
+                       }
+                       if (member_lookup == null) {
+                               MemberLookupFailed (
+                                       ec, expr_type, expr_type, Identifier, null, loc);
+                               return null;
+                       }
+
+                       if (member_lookup is TypeExpr) {
+                               if (!(expr is TypeExpr) && !(expr is SimpleName)) {
+                                       Error (572, "Can't reference type `" + Identifier + "' through an expression; try `" +
+                                              member_lookup.Type + "' instead");
+                                       return null;
+                               }
+
+                               return member_lookup;
+                       }
+
+                       if (args != null) {
+                               string full_name = expr_type + "." + Identifier;
+
+                               if (member_lookup is FieldExpr) {
+                                       Report.Error (307, loc, "The field `{0}' cannot " +
+                                                     "be used with type arguments", full_name);
+                                       return null;
+                               } else if (member_lookup is EventExpr) {
+                                       Report.Error (307, loc, "The event `{0}' cannot " +
+                                                     "be used with type arguments", full_name);
+                                       return null;
+                               } else if (member_lookup is PropertyExpr) {
+                                       Report.Error (307, loc, "The property `{0}' cannot " +
+                                                     "be used with type arguments", full_name);
+                                       return null;
+                               }
+                       }
+                       
+                       member_lookup = ResolveMemberAccess (ec, member_lookup, expr, loc, original);
+                       if (member_lookup == null)
+                               return null;
+
+                       if (args != null) {
+                               MethodGroupExpr mg = member_lookup as MethodGroupExpr;
+                               if (mg == null)
+                                       throw new InternalErrorException ();
+
+                               return mg.ResolveGeneric (ec, args);
+                       }
+
+                       // The following DoResolve/DoResolveLValue will do the definite assignment
+                       // check.
+
+                       if (right_side != null)
+                               member_lookup = member_lookup.DoResolveLValue (ec, right_side);
+                       else
+                               member_lookup = member_lookup.DoResolve (ec);
+
+                       return member_lookup;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       return DoResolve (ec, null, ResolveFlags.VariableOrValue |
+                                         ResolveFlags.SimpleName | ResolveFlags.Type);
+               }
+
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       return DoResolve (ec, right_side, ResolveFlags.VariableOrValue |
+                                         ResolveFlags.SimpleName | ResolveFlags.Type);
+               }
+
+               public override Expression ResolveAsTypeStep (EmitContext ec)
+               {
+                       string fname = null;
+                       MemberAccess full_expr = this;
+                       while (full_expr != null) {
+                               if (fname != null)
+                                       fname = String.Concat (full_expr.Identifier, ".", fname);
+                               else
+                                       fname = full_expr.Identifier;
+
+                               fname = MemberName.MakeName (fname, args);
+
+                               if (full_expr.Expr is SimpleName) {
+                                       string full_name = String.Concat (((SimpleName) full_expr.Expr).Name, ".", fname);
+                                       Type fully_qualified = ec.DeclSpace.FindType (loc, full_name);
+                                       if (fully_qualified != null) {
+                                               if (args == null)
+                                                       return new TypeExpression (fully_qualified, loc);
+
+                                               ConstructedType ctype = new ConstructedType (fully_qualified, args, loc);
+                                               return ctype.ResolveAsTypeStep (ec);
+                                       }
+                               }
+
+                               full_expr = full_expr.Expr as MemberAccess;
+                       }
+
+                       Expression new_expr = expr.ResolveAsTypeStep (ec);
+
+                       if (new_expr == null)
+                               return null;
+
+                       if (new_expr is SimpleName){
+                               SimpleName child_expr = (SimpleName) new_expr;
+                               string fqname = DeclSpace.MakeFQN (child_expr.Name, Identifier);
+                               
+                               if (args != null)
+                                       new_expr = new ConstructedType (fqname, args, loc);
+                               else
+                                       new_expr = new SimpleName (fqname, loc);
+
+                               return new_expr.ResolveAsTypeStep (ec);
+                       }
+
+                       TypeExpr tnew_expr = new_expr.ResolveAsTypeTerminal (ec);
+                       if (tnew_expr == null)
+                               return null;
+
+                       Type expr_type = tnew_expr.Type;
+
+                       if (expr_type.IsPointer){
+                               Error (23, "The `.' operator can not be applied to pointer operands (" +
+                                      TypeManager.CSharpName (expr_type) + ")");
+                               return null;
+                       }
+
+                       Expression member_lookup;
+                       string lookup_id;
+                       lookup_id = MemberName.MakeName (Identifier, args);
+                       member_lookup = MemberLookupFinal (
+                               ec, expr_type, expr_type, lookup_id, loc);
+                       if (member_lookup == null)
+                               return null;
+
+                       TypeExpr texpr = member_lookup as TypeExpr;
+                       if (texpr == null)
+                               return null;
+
+                       texpr = texpr.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return null;
+
+                       TypeArguments the_args = args;
+                       if (TypeManager.HasGenericArguments (expr_type)) {
+                               Type[] decl_args = TypeManager.GetTypeArguments (expr_type);
+
+                               TypeArguments new_args = new TypeArguments (loc);
+                               foreach (Type decl in decl_args)
+                                       new_args.Add (new TypeExpression (decl, loc));
+
+                               if (args != null)
+                                       new_args.Add (args);
+
+                               the_args = new_args;
+                       }
+
+                       if (the_args != null) {
+                               ConstructedType ctype = new ConstructedType (texpr.Type, the_args, loc);
+                               return ctype.ResolveAsTypeStep (ec);
+                       }
+
+                       return texpr;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new Exception ("Should not happen");
+               }
+
+               public override string ToString ()
+               {
+                       return expr + "." + MemberName.MakeName (Identifier, args);
+               }
+       }
+
+       /// <summary>
+       ///   Implements checked expressions
+       /// </summary>
+       public class CheckedExpr : Expression {
+
+               public Expression Expr;
+
+               public CheckedExpr (Expression e, Location l)
+               {
+                       Expr = e;
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       bool last_check = ec.CheckState;
+                       bool last_const_check = ec.ConstantCheckState;
+
+                       ec.CheckState = true;
+                       ec.ConstantCheckState = true;
+                       Expr = Expr.Resolve (ec);
+                       ec.CheckState = last_check;
+                       ec.ConstantCheckState = last_const_check;
+                       
+                       if (Expr == null)
+                               return null;
+
+                       if (Expr is Constant)
+                               return Expr;
+                       
+                       eclass = Expr.eclass;
+                       type = Expr.Type;
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       bool last_check = ec.CheckState;
+                       bool last_const_check = ec.ConstantCheckState;
+                       
+                       ec.CheckState = true;
+                       ec.ConstantCheckState = true;
+                       Expr.Emit (ec);
+                       ec.CheckState = last_check;
+                       ec.ConstantCheckState = last_const_check;
+               }
+               
+       }
+
+       /// <summary>
+       ///   Implements the unchecked expression
+       /// </summary>
+       public class UnCheckedExpr : Expression {
+
+               public Expression Expr;
+
+               public UnCheckedExpr (Expression e, Location l)
+               {
+                       Expr = e;
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       bool last_check = ec.CheckState;
+                       bool last_const_check = ec.ConstantCheckState;
+
+                       ec.CheckState = false;
+                       ec.ConstantCheckState = false;
+                       Expr = Expr.Resolve (ec);
+                       ec.CheckState = last_check;
+                       ec.ConstantCheckState = last_const_check;
+
+                       if (Expr == null)
+                               return null;
+
+                       if (Expr is Constant)
+                               return Expr;
+                       
+                       eclass = Expr.eclass;
+                       type = Expr.Type;
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       bool last_check = ec.CheckState;
+                       bool last_const_check = ec.ConstantCheckState;
+                       
+                       ec.CheckState = false;
+                       ec.ConstantCheckState = false;
+                       Expr.Emit (ec);
+                       ec.CheckState = last_check;
+                       ec.ConstantCheckState = last_const_check;
+               }
+               
+       }
+
+       /// <summary>
+       ///   An Element Access expression.
+       ///
+       ///   During semantic analysis these are transformed into 
+       ///   IndexerAccess, ArrayAccess or a PointerArithmetic.
+       /// </summary>
+       public class ElementAccess : Expression {
+               public ArrayList  Arguments;
+               public Expression Expr;
+               
+               public ElementAccess (Expression e, ArrayList e_list, Location l)
+               {
+                       Expr = e;
+
+                       loc  = l;
+                       
+                       if (e_list == null)
+                               return;
+                       
+                       Arguments = new ArrayList ();
+                       foreach (Expression tmp in e_list)
+                               Arguments.Add (new Argument (tmp, Argument.AType.Expression));
+                       
+               }
+
+               bool CommonResolve (EmitContext ec)
+               {
+                       Expr = Expr.Resolve (ec);
+
+                       if (Expr == null) 
+                               return false;
+
+                       if (Arguments == null)
+                               return false;
+
+                       foreach (Argument a in Arguments){
+                               if (!a.Resolve (ec, loc))
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               Expression MakePointerAccess (EmitContext ec)
+               {
+                       Type t = Expr.Type;
+
+                       if (t == TypeManager.void_ptr_type){
+                               Error (242, "The array index operation is not valid for void pointers");
+                               return null;
+                       }
+                       if (Arguments.Count != 1){
+                               Error (196, "A pointer must be indexed by a single value");
+                               return null;
+                       }
+                       Expression p;
+
+                       p = new PointerArithmetic (true, Expr, ((Argument)Arguments [0]).Expr, t, loc).Resolve (ec);
+                       if (p == null)
+                               return null;
+                       return new Indirection (p, loc).Resolve (ec);
+               }
+               
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       if (!CommonResolve (ec))
+                               return null;
+
+                       //
+                       // We perform some simple tests, and then to "split" the emit and store
+                       // code we create an instance of a different class, and return that.
+                       //
+                       // I am experimenting with this pattern.
+                       //
+                       Type t = Expr.Type;
+
+                       if (t == TypeManager.array_type){
+                               Report.Error (21, loc, "Cannot use indexer on System.Array");
+                               return null;
+                       }
+                       
+                       if (t.IsArray)
+                               return (new ArrayAccess (this, loc)).Resolve (ec);
+                       else if (t.IsPointer)
+                               return MakePointerAccess (ec);
+                       else
+                               return (new IndexerAccess (this, loc)).Resolve (ec);
+               }
+
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       if (!CommonResolve (ec))
+                               return null;
+
+                       Type t = Expr.Type;
+                       if (t.IsArray)
+                               return (new ArrayAccess (this, loc)).ResolveLValue (ec, right_side);
+                       else if (t.IsPointer)
+                               return MakePointerAccess (ec);
+                       else
+                               return (new IndexerAccess (this, loc)).ResolveLValue (ec, right_side);
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       throw new Exception ("Should never be reached");
+               }
+       }
+
+       /// <summary>
+       ///   Implements array access 
+       /// </summary>
+       public class ArrayAccess : Expression, IAssignMethod, IMemoryLocation {
+               //
+               // Points to our "data" repository
+               //
+               ElementAccess ea;
+
+               LocalTemporary temp;
+               bool prepared;
+               
+               public ArrayAccess (ElementAccess ea_data, Location l)
+               {
+                       ea = ea_data;
+                       eclass = ExprClass.Variable;
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+#if false
+                       ExprClass eclass = ea.Expr.eclass;
+
+                       // As long as the type is valid
+                       if (!(eclass == ExprClass.Variable || eclass == ExprClass.PropertyAccess ||
+                             eclass == ExprClass.Value)) {
+                               ea.Expr.Error_UnexpectedKind ("variable or value");
+                               return null;
+                       }
+#endif
+
+                       Type t = ea.Expr.Type;
+                       if (t.GetArrayRank () != ea.Arguments.Count){
+                               ea.Error (22,
+                                         "Incorrect number of indexes for array " +
+                                         " expected: " + t.GetArrayRank () + " got: " +
+                                         ea.Arguments.Count);
+                               return null;
+                       }
+
+                        type = TypeManager.GetElementType (t);
+                        if (type.IsPointer && !ec.InUnsafe){
+                               UnsafeError (ea.Location);
+                               return null;
+                       }
+
+                       foreach (Argument a in ea.Arguments){
+                               Type argtype = a.Type;
+
+                               if (argtype == TypeManager.int32_type ||
+                                   argtype == TypeManager.uint32_type ||
+                                   argtype == TypeManager.int64_type ||
+                                   argtype == TypeManager.uint64_type) {
+                                       Constant c = a.Expr as Constant;
+                                       if (c != null && c.IsNegative) {
+                                               Report.Warning (251, 2, a.Expr.Location, "Indexing an array with a negative index (array indices always start at zero)");
+                                       }
+                                       continue;
+                               }
+
+                               //
+                               // Mhm.  This is strage, because the Argument.Type is not the same as
+                               // Argument.Expr.Type: the value changes depending on the ref/out setting.
+                               //
+                               // Wonder if I will run into trouble for this.
+                               //
+                               a.Expr = ExpressionToArrayArgument (ec, a.Expr, ea.Location);
+                               if (a.Expr == null)
+                                       return null;
+                       }
+                       
+                       eclass = ExprClass.Variable;
+
+                       return this;
+               }
+
+               /// <summary>
+               ///    Emits the right opcode to load an object of Type `t'
+               ///    from an array of T
+               /// </summary>
+               static public void EmitLoadOpcode (ILGenerator ig, Type type)
+               {
+                       if (type == TypeManager.byte_type || type == TypeManager.bool_type)
+                               ig.Emit (OpCodes.Ldelem_U1);
+                       else if (type == TypeManager.sbyte_type)
+                               ig.Emit (OpCodes.Ldelem_I1);
+                       else if (type == TypeManager.short_type)
+                               ig.Emit (OpCodes.Ldelem_I2);
+                       else if (type == TypeManager.ushort_type || type == TypeManager.char_type)
+                               ig.Emit (OpCodes.Ldelem_U2);
+                       else if (type == TypeManager.int32_type)
+                               ig.Emit (OpCodes.Ldelem_I4);
+                       else if (type == TypeManager.uint32_type)
+                               ig.Emit (OpCodes.Ldelem_U4);
+                       else if (type == TypeManager.uint64_type)
+                               ig.Emit (OpCodes.Ldelem_I8);
+                       else if (type == TypeManager.int64_type)
+                               ig.Emit (OpCodes.Ldelem_I8);
+                       else if (type == TypeManager.float_type)
+                               ig.Emit (OpCodes.Ldelem_R4);
+                       else if (type == TypeManager.double_type)
+                               ig.Emit (OpCodes.Ldelem_R8);
+                       else if (type == TypeManager.intptr_type)
+                               ig.Emit (OpCodes.Ldelem_I);
+                       else if (TypeManager.IsEnumType (type)){
+                               EmitLoadOpcode (ig, TypeManager.EnumToUnderlying (type));
+                       } else if (type.IsValueType){
+                               ig.Emit (OpCodes.Ldelema, type);
+                               ig.Emit (OpCodes.Ldobj, type);
+                       } else if (type.IsGenericParameter)
+                               ig.Emit (OpCodes.Ldelem_Any, type);
+                       else
+                               ig.Emit (OpCodes.Ldelem_Ref);
+               }
+
+               /// <summary>
+               ///    Returns the right opcode to store an object of Type `t'
+               ///    from an array of T.  
+               /// </summary>
+               static public OpCode GetStoreOpcode (Type t, out bool is_stobj, out bool has_type_arg)
+               {
+                       //Console.WriteLine (new System.Diagnostics.StackTrace ());
+                       has_type_arg = false; is_stobj = false;
+                       t = TypeManager.TypeToCoreType (t);
+                       if (TypeManager.IsEnumType (t))
+                               t = TypeManager.EnumToUnderlying (t);
+                       if (t == TypeManager.byte_type || t == TypeManager.sbyte_type ||
+                           t == TypeManager.bool_type)
+                               return OpCodes.Stelem_I1;
+                       else if (t == TypeManager.short_type || t == TypeManager.ushort_type ||
+                                t == TypeManager.char_type)
+                               return OpCodes.Stelem_I2;
+                       else if (t == TypeManager.int32_type || t == TypeManager.uint32_type)
+                               return OpCodes.Stelem_I4;
+                       else if (t == TypeManager.int64_type || t == TypeManager.uint64_type)
+                               return OpCodes.Stelem_I8;
+                       else if (t == TypeManager.float_type)
+                               return OpCodes.Stelem_R4;
+                       else if (t == TypeManager.double_type)
+                               return OpCodes.Stelem_R8;
+                       else if (t == TypeManager.intptr_type) {
+                                has_type_arg = true;
+                               is_stobj = true;
+                                return OpCodes.Stobj;
+                       } else if (t.IsValueType) {
+                               has_type_arg = true;
+                               is_stobj = true;
+                               return OpCodes.Stobj;
+                       } else if (t.IsGenericParameter) {
+                               has_type_arg = true;
+                               return OpCodes.Stelem_Any;
+                       } else
+                               return OpCodes.Stelem_Ref;
+               }
+
+               MethodInfo FetchGetMethod ()
+               {
+                       ModuleBuilder mb = CodeGen.Module.Builder;
+                       int arg_count = ea.Arguments.Count;
+                       Type [] args = new Type [arg_count];
+                       MethodInfo get;
+                       
+                       for (int i = 0; i < arg_count; i++){
+                               //args [i++] = a.Type;
+                               args [i] = TypeManager.int32_type;
+                       }
+                       
+                       get = mb.GetArrayMethod (
+                               ea.Expr.Type, "Get",
+                               CallingConventions.HasThis |
+                               CallingConventions.Standard,
+                               type, args);
+                       return get;
+               }
+                               
+
+               MethodInfo FetchAddressMethod ()
+               {
+                       ModuleBuilder mb = CodeGen.Module.Builder;
+                       int arg_count = ea.Arguments.Count;
+                       Type [] args = new Type [arg_count];
+                       MethodInfo address;
+                       Type ret_type;
+                       
+                       ret_type = TypeManager.GetReferenceType (type);
+                       
+                       for (int i = 0; i < arg_count; i++){
+                               //args [i++] = a.Type;
+                               args [i] = TypeManager.int32_type;
+                       }
+                       
+                       address = mb.GetArrayMethod (
+                               ea.Expr.Type, "Address",
+                               CallingConventions.HasThis |
+                               CallingConventions.Standard,
+                               ret_type, args);
+
+                       return address;
+               }
+
+               //
+               // Load the array arguments into the stack.
+               //
+               // If we have been requested to cache the values (cached_locations array
+               // initialized), then load the arguments the first time and store them
+               // in locals.  otherwise load from local variables.
+               //
+               void LoadArrayAndArguments (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       ea.Expr.Emit (ec);
+                       foreach (Argument a in ea.Arguments){
+                               Type argtype = a.Expr.Type;
+                               
+                               a.Expr.Emit (ec);
+                               
+                               if (argtype == TypeManager.int64_type)
+                                       ig.Emit (OpCodes.Conv_Ovf_I);
+                               else if (argtype == TypeManager.uint64_type)
+                                       ig.Emit (OpCodes.Conv_Ovf_I_Un);
+                       }
+               }
+
+               public void Emit (EmitContext ec, bool leave_copy)
+               {
+                       int rank = ea.Expr.Type.GetArrayRank ();
+                       ILGenerator ig = ec.ig;
+
+                       if (!prepared) {
+                               LoadArrayAndArguments (ec);
+                               
+                               if (rank == 1)
+                                       EmitLoadOpcode (ig, type);
+                               else {
+                                       MethodInfo method;
+                                       
+                                       method = FetchGetMethod ();
+                                       ig.Emit (OpCodes.Call, method);
+                               }
+                       } else
+                               LoadFromPtr (ec.ig, this.type);
+                       
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               temp = new LocalTemporary (ec, this.type);
+                               temp.Store (ec);
+                       }
+               }
+               
+               public override void Emit (EmitContext ec)
+               {
+                       Emit (ec, false);
+               }
+
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+               {
+                       int rank = ea.Expr.Type.GetArrayRank ();
+                       ILGenerator ig = ec.ig;
+                       Type t = source.Type;
+                       prepared = prepare_for_load;
+
+                       if (prepare_for_load) {
+                               AddressOf (ec, AddressOp.LoadStore);
+                               ec.ig.Emit (OpCodes.Dup);
+                               source.Emit (ec);
+                               if (leave_copy) {
+                                       ec.ig.Emit (OpCodes.Dup);
+                                       temp = new LocalTemporary (ec, this.type);
+                                       temp.Store (ec);
+                               }
+                               StoreFromPtr (ec.ig, t);
+                               
+                               if (temp != null)
+                                       temp.Emit (ec);
+                               
+                               return;
+                       }
+                       
+                       LoadArrayAndArguments (ec);
+
+                       if (rank == 1) {
+                               bool is_stobj, has_type_arg;
+                               OpCode op = GetStoreOpcode (t, out is_stobj, out has_type_arg);
+
+                               //
+                               // The stobj opcode used by value types will need
+                               // an address on the stack, not really an array/array
+                               // pair
+                               //
+                               if (is_stobj)
+                                       ig.Emit (OpCodes.Ldelema, t);
+                               
+                               source.Emit (ec);
+                               if (leave_copy) {
+                                       ec.ig.Emit (OpCodes.Dup);
+                                       temp = new LocalTemporary (ec, this.type);
+                                       temp.Store (ec);
+                               }
+                               
+                               if (is_stobj)
+                                       ig.Emit (OpCodes.Stobj, t);
+                               else if (has_type_arg)
+                                       ig.Emit (op, t);
+                               else
+                                       ig.Emit (op);
+                       } else {
+                               ModuleBuilder mb = CodeGen.Module.Builder;
+                               int arg_count = ea.Arguments.Count;
+                               Type [] args = new Type [arg_count + 1];
+                               MethodInfo set;
+                               
+                               source.Emit (ec);
+                               if (leave_copy) {
+                                       ec.ig.Emit (OpCodes.Dup);
+                                       temp = new LocalTemporary (ec, this.type);
+                                       temp.Store (ec);
+                               }
+                               
+                               for (int i = 0; i < arg_count; i++){
+                                       //args [i++] = a.Type;
+                                       args [i] = TypeManager.int32_type;
+                               }
+
+                               args [arg_count] = type;
+                               
+                               set = mb.GetArrayMethod (
+                                       ea.Expr.Type, "Set",
+                                       CallingConventions.HasThis |
+                                       CallingConventions.Standard,
+                                       TypeManager.void_type, args);
+                               
+                               ig.Emit (OpCodes.Call, set);
+                       }
+                       
+                       if (temp != null)
+                               temp.Emit (ec);
+               }
+
+               public void AddressOf (EmitContext ec, AddressOp mode)
+               {
+                       int rank = ea.Expr.Type.GetArrayRank ();
+                       ILGenerator ig = ec.ig;
+
+                       LoadArrayAndArguments (ec);
+
+                       if (rank == 1){
+                               ig.Emit (OpCodes.Ldelema, type);
+                       } else {
+                               MethodInfo address = FetchAddressMethod ();
+                               ig.Emit (OpCodes.Call, address);
+                       }
+               }
+       }
+
+       
+       class Indexers {
+               public ArrayList Properties;
+               static Hashtable map;
+
+               public struct Indexer {
+                       public readonly Type Type;
+                       public readonly MethodInfo Getter, Setter;
+
+                       public Indexer (Type type, MethodInfo get, MethodInfo set)
+                       {
+                               this.Type = type;
+                               this.Getter = get;
+                               this.Setter = set;
+                       }
+               }
+
+               static Indexers ()
+               {
+                       map = new Hashtable ();
+               }
+
+               Indexers ()
+               {
+                       Properties = new ArrayList ();
+               }
+                               
+               void Append (MemberInfo [] mi)
+               {
+                       foreach (PropertyInfo property in mi){
+                               MethodInfo get, set;
+                               
+                               get = property.GetGetMethod (true);
+                               set = property.GetSetMethod (true);
+                               Properties.Add (new Indexer (property.PropertyType, get, set));
+                       }
+               }
+
+               static private MemberInfo [] GetIndexersForTypeOrInterface (Type caller_type, Type lookup_type)
+               {
+                       string p_name = TypeManager.IndexerPropertyName (lookup_type);
+
+                       MemberInfo [] mi = TypeManager.MemberLookup (
+                               caller_type, caller_type, lookup_type, MemberTypes.Property,
+                               BindingFlags.Public | BindingFlags.Instance |
+                               BindingFlags.DeclaredOnly, p_name, null);
+
+                       if (mi == null || mi.Length == 0)
+                               return null;
+
+                       return mi;
+               }
+               
+               static public Indexers GetIndexersForType (Type caller_type, Type lookup_type, Location loc) 
+               {
+                       Indexers ix = (Indexers) map [lookup_type];
+
+                       if (ix != null)
+                               return ix;
+
+                       Type copy = lookup_type;
+                       while (copy != TypeManager.object_type && copy != null){
+                               MemberInfo [] mi = GetIndexersForTypeOrInterface (caller_type, copy);
+
+                               if (mi != null){
+                                       if (ix == null)
+                                               ix = new Indexers ();
+
+                                       ix.Append (mi);
+                               }
+                                       
+                               copy = copy.BaseType;
+                       }
+
+                       if (!lookup_type.IsInterface)
+                               return ix;
+
+                       Type [] ifaces = TypeManager.GetInterfaces (lookup_type);
+                       if (ifaces != null) {
+                               foreach (Type itype in ifaces) {
+                                       MemberInfo [] mi = GetIndexersForTypeOrInterface (caller_type, itype);
+                                       if (mi != null){
+                                               if (ix == null)
+                                                       ix = new Indexers ();
+                                       
+                                               ix.Append (mi);
+                                       }
+                               }
+                       }
+
+                       return ix;
+               }
+       }
+
+       /// <summary>
+       ///   Expressions that represent an indexer call.
+       /// </summary>
+       public class IndexerAccess : Expression, IAssignMethod {
+               //
+               // Points to our "data" repository
+               //
+               MethodInfo get, set;
+               ArrayList set_arguments;
+               bool is_base_indexer;
+
+               protected Type indexer_type;
+               protected Type current_type;
+               protected Expression instance_expr;
+               protected ArrayList arguments;
+               
+               public IndexerAccess (ElementAccess ea, Location loc)
+                       : this (ea.Expr, false, loc)
+               {
+                       this.arguments = ea.Arguments;
+               }
+
+               protected IndexerAccess (Expression instance_expr, bool is_base_indexer,
+                                        Location loc)
+               {
+                       this.instance_expr = instance_expr;
+                       this.is_base_indexer = is_base_indexer;
+                       this.eclass = ExprClass.Value;
+                       this.loc = loc;
+               }
+
+               protected virtual bool CommonResolve (EmitContext ec)
+               {
+                       indexer_type = instance_expr.Type;
+                       current_type = ec.ContainerType;
+
+                       return true;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       ArrayList AllGetters = new ArrayList();
+                       if (!CommonResolve (ec))
+                               return null;
+
+                       //
+                       // Step 1: Query for all `Item' *properties*.  Notice
+                       // that the actual methods are pointed from here.
+                       //
+                       // This is a group of properties, piles of them.  
+
+                       bool found_any = false, found_any_getters = false;
+                       Type lookup_type = indexer_type;
+
+                       Indexers ilist;
+                       ilist = Indexers.GetIndexersForType (current_type, lookup_type, loc);
+                       if (ilist != null) {
+                               found_any = true;
+                               if (ilist.Properties != null) {
+                                       foreach (Indexers.Indexer ix in ilist.Properties) {
+                                               if (ix.Getter != null)
+                                                       AllGetters.Add(ix.Getter);
+                                       }
+                               }
+                       }
+
+                       if (AllGetters.Count > 0) {
+                               found_any_getters = true;
+                               get = (MethodInfo) Invocation.OverloadResolve (
+                                       ec, new MethodGroupExpr (AllGetters, loc),
+                                       arguments, false, loc);
+                       }
+
+                       if (!found_any) {
+                               Report.Error (21, loc,
+                                             "Type `" + TypeManager.CSharpName (indexer_type) +
+                                             "' does not have any indexers defined");
+                               return null;
+                       }
+
+                       if (!found_any_getters) {
+                               Error (154, "indexer can not be used in this context, because " +
+                                      "it lacks a `get' accessor");
+                               return null;
+                       }
+
+                       if (get == null) {
+                               Error (1501, "No Overload for method `this' takes `" +
+                                      arguments.Count + "' arguments");
+                               return null;
+                       }
+
+                       //
+                       // Only base will allow this invocation to happen.
+                       //
+                       if (get.IsAbstract && this is BaseIndexerAccess){
+                               Report.Error (205, loc, "Cannot call an abstract base indexer: " + Invocation.FullMethodDesc (get));
+                               return null;
+                       }
+
+                       type = get.ReturnType;
+                       if (type.IsPointer && !ec.InUnsafe){
+                               UnsafeError (loc);
+                               return null;
+                       }
+
+                       instance_expr.CheckMarshallByRefAccess (ec.ContainerType);
+                       
+                       eclass = ExprClass.IndexerAccess;
+                       return this;
+               }
+
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       ArrayList AllSetters = new ArrayList();
+                       if (!CommonResolve (ec))
+                               return null;
+
+                       bool found_any = false, found_any_setters = false;
+
+                       Indexers ilist = Indexers.GetIndexersForType (current_type, indexer_type, loc);
+                       if (ilist != null) {
+                               found_any = true;
+                               if (ilist.Properties != null) {
+                                       foreach (Indexers.Indexer ix in ilist.Properties) {
+                                               if (ix.Setter != null)
+                                                       AllSetters.Add(ix.Setter);
+                                       }
+                               }
+                       }
+                       if (AllSetters.Count > 0) {
+                               found_any_setters = true;
+                               set_arguments = (ArrayList) arguments.Clone ();
+                               set_arguments.Add (new Argument (right_side, Argument.AType.Expression));
+                               set = (MethodInfo) Invocation.OverloadResolve (
+                                       ec, new MethodGroupExpr (AllSetters, loc),
+                                       set_arguments, false, loc);
+                       }
+
+                       if (!found_any) {
+                               Report.Error (21, loc,
+                                             "Type `" + TypeManager.CSharpName (indexer_type) +
+                                             "' does not have any indexers defined");
+                               return null;
+                       }
+
+                       if (!found_any_setters) {
+                               Error (154, "indexer can not be used in this context, because " +
+                                      "it lacks a `set' accessor");
+                               return null;
+                       }
+
+                       if (set == null) {
+                               Error (1501, "No Overload for method `this' takes `" +
+                                      arguments.Count + "' arguments");
+                               return null;
+                       }
+
+                       //
+                       // Only base will allow this invocation to happen.
+                       //
+                       if (set.IsAbstract && this is BaseIndexerAccess){
+                               Report.Error (205, loc, "Cannot call an abstract base indexer: " + Invocation.FullMethodDesc (set));
+                               return null;
+                       }
+
+                       //
+                       // Now look for the actual match in the list of indexers to set our "return" type
+                       //
+                       type = TypeManager.void_type;   // default value
+                       foreach (Indexers.Indexer ix in ilist.Properties){
+                               if (ix.Setter == set){
+                                       type = ix.Type;
+                                       break;
+                               }
+                       }
+                       
+                       instance_expr.CheckMarshallByRefAccess (ec.ContainerType);
+
+                       eclass = ExprClass.IndexerAccess;
+                       return this;
+               }
+               
+               bool prepared = false;
+               LocalTemporary temp;
+               
+               public void Emit (EmitContext ec, bool leave_copy)
+               {
+                       Invocation.EmitCall (ec, is_base_indexer, false, instance_expr, get, arguments, loc, prepared, false);
+                       if (leave_copy) {
+                               ec.ig.Emit (OpCodes.Dup);
+                               temp = new LocalTemporary (ec, Type);
+                               temp.Store (ec);
+                       }
+               }
+               
+               //
+               // source is ignored, because we already have a copy of it from the
+               // LValue resolution and we have already constructed a pre-cached
+               // version of the arguments (ea.set_arguments);
+               //
+               public void EmitAssign (EmitContext ec, Expression source, bool leave_copy, bool prepare_for_load)
+               {
+                       prepared = prepare_for_load;
+                       Argument a = (Argument) set_arguments [set_arguments.Count - 1];
+                       
+                       if (prepared) {
+                               source.Emit (ec);
+                               if (leave_copy) {
+                                       ec.ig.Emit (OpCodes.Dup);
+                                       temp = new LocalTemporary (ec, Type);
+                                       temp.Store (ec);
+                               }
+                       } else if (leave_copy) {
+                               temp = new LocalTemporary (ec, Type);
+                               source.Emit (ec);
+                               temp.Store (ec);
+                               a.Expr = temp;
+                       }
+                       
+                       Invocation.EmitCall (ec, is_base_indexer, false, instance_expr, set, set_arguments, loc, false, prepared);
+                       
+                       if (temp != null)
+                               temp.Emit (ec);
+               }
+               
+               
+               public override void Emit (EmitContext ec)
+               {
+                       Emit (ec, false);
+               }
+       }
+
+       /// <summary>
+       ///   The base operator for method names
+       /// </summary>
+       public class BaseAccess : Expression {
+               public string member;
+               
+               public BaseAccess (string member, Location l)
+               {
+                       this.member = member;
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       Expression c = CommonResolve (ec);
+
+                       if (c == null)
+                               return null;
+
+                       //
+                       // MethodGroups use this opportunity to flag an error on lacking ()
+                       //
+                       if (!(c is MethodGroupExpr))
+                               return c.Resolve (ec);
+                       return c;
+               }
+
+               public override Expression DoResolveLValue (EmitContext ec, Expression right_side)
+               {
+                       Expression c = CommonResolve (ec);
+
+                       if (c == null)
+                               return null;
+
+                       //
+                       // MethodGroups use this opportunity to flag an error on lacking ()
+                       //
+                       if (! (c is MethodGroupExpr))
+                               return c.DoResolveLValue (ec, right_side);
+
+                       return c;
+               }
+
+               Expression CommonResolve (EmitContext ec)
+               {
+                       Expression member_lookup;
+                       Type current_type = ec.ContainerType;
+                       Type base_type = current_type.BaseType;
+                       Expression e;
+
+                       if (ec.IsStatic){
+                               Error (1511, "Keyword base is not allowed in static method");
+                               return null;
+                       }
+
+                       if (ec.IsFieldInitializer){
+                               Error (1512, "Keyword base is not available in the current context");
+                               return null;
+                       }
+                       
+                       member_lookup = MemberLookup (ec, ec.ContainerType, null, base_type,
+                                                     member, AllMemberTypes, AllBindingFlags,
+                                                     loc);
+                       if (member_lookup == null) {
+                               MemberLookupFailed (
+                                       ec, base_type, base_type, member, null, loc);
+                               return null;
+                       }
+
+                       Expression left;
+                       
+                       if (ec.IsStatic)
+                               left = new TypeExpression (base_type, loc);
+                       else
+                               left = ec.GetThis (loc);
+                       
+                       e = MemberAccess.ResolveMemberAccess (ec, member_lookup, left, loc, null);
+
+                       if (e is PropertyExpr){
+                               PropertyExpr pe = (PropertyExpr) e;
+
+                               pe.IsBase = true;
+                       }
+
+                       if (e is MethodGroupExpr)
+                               ((MethodGroupExpr) e).IsBase = true;
+
+                       return e;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       throw new Exception ("Should never be called"); 
+               }
+       }
+
+       /// <summary>
+       ///   The base indexer operator
+       /// </summary>
+       public class BaseIndexerAccess : IndexerAccess {
+               public BaseIndexerAccess (ArrayList args, Location loc)
+                       : base (null, true, loc)
+               {
+                       arguments = new ArrayList ();
+                       foreach (Expression tmp in args)
+                               arguments.Add (new Argument (tmp, Argument.AType.Expression));
+               }
+
+               protected override bool CommonResolve (EmitContext ec)
+               {
+                       instance_expr = ec.GetThis (loc);
+
+                       current_type = ec.ContainerType.BaseType;
+                       indexer_type = current_type;
+
+                       foreach (Argument a in arguments){
+                               if (!a.Resolve (ec, loc))
+                                       return false;
+                       }
+
+                       return true;
+               }
+       }
+       
+       /// <summary>
+       ///   This class exists solely to pass the Type around and to be a dummy
+       ///   that can be passed to the conversion functions (this is used by
+       ///   foreach implementation to typecast the object return value from
+       ///   get_Current into the proper type.  All code has been generated and
+       ///   we only care about the side effect conversions to be performed
+       ///
+       ///   This is also now used as a placeholder where a no-action expression
+       ///   is needed (the `New' class).
+       /// </summary>
+       public class EmptyExpression : Expression {
+               public static readonly EmptyExpression Null = new EmptyExpression ();
+
+               // TODO: should be protected
+               public EmptyExpression ()
+               {
+                       type = TypeManager.object_type;
+                       eclass = ExprClass.Value;
+                       loc = Location.Null;
+               }
+
+               public EmptyExpression (Type t)
+               {
+                       type = t;
+                       eclass = ExprClass.Value;
+                       loc = Location.Null;
+               }
+               
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       // nothing, as we only exist to not do anything.
+               }
+
+               //
+               // This is just because we might want to reuse this bad boy
+               // instead of creating gazillions of EmptyExpressions.
+               // (CanImplicitConversion uses it)
+               //
+               public void SetType (Type t)
+               {
+                       type = t;
+               }
+       }
+
+       public class UserCast : Expression {
+               MethodBase method;
+               Expression source;
+               
+               public UserCast (MethodInfo method, Expression source, Location l)
+               {
+                       this.method = method;
+                       this.source = source;
+                       type = method.ReturnType;
+                       eclass = ExprClass.Value;
+                       loc = l;
+               }
+
+               public Expression Source {
+                       get {
+                               return source;
+                       }
+               }
+                       
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       //
+                       // We are born fully resolved
+                       //
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       source.Emit (ec);
+                       
+                       if (method is MethodInfo)
+                               ig.Emit (OpCodes.Call, (MethodInfo) method);
+                       else
+                               ig.Emit (OpCodes.Call, (ConstructorInfo) method);
+
+               }
+       }
+
+       // <summary>
+       //   This class is used to "construct" the type during a typecast
+       //   operation.  Since the Type.GetType class in .NET can parse
+       //   the type specification, we just use this to construct the type
+       //   one bit at a time.
+       // </summary>
+       public class ComposedCast : TypeExpr {
+               Expression left;
+               string dim;
+               
+               public ComposedCast (Expression left, string dim, Location l)
+               {
+                       this.left = left;
+                       this.dim = dim;
+                       loc = l;
+               }
+
+               protected override TypeExpr DoResolveAsTypeStep (EmitContext ec)
+               {
+                       TypeExpr lexpr = left.ResolveAsTypeTerminal (ec);
+                       if (lexpr == null)
+                               return null;
+
+                       Type ltype = lexpr.Type;
+
+                       if ((ltype == TypeManager.void_type) && (dim != "*")) {
+                               Report.Error (1547, Location,
+                                             "Keyword 'void' cannot be used in this context");
+                               return null;
+                       }
+
+                       int pos = 0;
+                       while ((pos < dim.Length) && (dim [pos] == '[')) {
+                               pos++;
+
+                               if (dim [pos] == ']') {
+                                       ltype = ltype.MakeArrayType ();
+                                       pos++;
+
+                                       if (pos < dim.Length)
+                                               continue;
+
+                                       type = ltype;
+                                       eclass = ExprClass.Type;
+                                       return this;
+                               }
+
+                               int rank = 0;
+                               while (dim [pos] == ',') {
+                                       pos++; rank++;
+                               }
+
+                               if ((dim [pos] != ']') || (pos != dim.Length-1))
+                                       return null;
+                                               
+                               type = ltype.MakeArrayType (rank + 1);
+                               eclass = ExprClass.Type;
+                               return this;
+                       }
+
+                       //
+                       // ltype.Fullname is already fully qualified, so we can skip
+                       // a lot of probes, and go directly to TypeManager.LookupType
+                       //
+                       string fname = ltype.FullName != null ? ltype.FullName : ltype.Name;
+                       string cname = fname + dim;
+                       type = TypeManager.LookupTypeDirect (cname);
+                       if (type == null){
+                               //
+                               // For arrays of enumerations we are having a problem
+                               // with the direct lookup.  Need to investigate.
+                               //
+                               // For now, fall back to the full lookup in that case.
+                               //
+                               type = RootContext.LookupType (ec.DeclSpace, cname, false, loc);
+                               if (type == null)
+                                       return null;
+                       }
+
+                       if (!ec.InUnsafe && type.IsPointer){
+                               UnsafeError (loc);
+                               return null;
+                       }
+                       
+                       eclass = ExprClass.Type;
+                       return this;
+               }
+
+               public override string Name {
+                       get {
+                               return left + dim;
+                       }
+               }
+       }
+
+       //
+       // This class is used to represent the address of an array, used
+       // only by the Fixed statement, this is like the C "&a [0]" construct.
+       //
+       public class ArrayPtr : Expression {
+               Expression array;
+               
+               public ArrayPtr (Expression array, Location l)
+               {
+                       Type array_type = TypeManager.GetElementType (array.Type);
+
+                       this.array = array;
+
+                       type = TypeManager.GetPointerType (array_type);
+                       eclass = ExprClass.Value;
+                       loc = l;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       array.Emit (ec);
+                       IntLiteral.EmitInt (ig, 0);
+                       ig.Emit (OpCodes.Ldelema, TypeManager.GetElementType (array.Type));
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       //
+                       // We are born fully resolved
+                       //
+                       return this;
+               }
+       }
+
+       //
+       // Used by the fixed statement
+       //
+       public class StringPtr : Expression {
+               LocalBuilder b;
+               
+               public StringPtr (LocalBuilder b, Location l)
+               {
+                       this.b = b;
+                       eclass = ExprClass.Value;
+                       type = TypeManager.char_ptr_type;
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       // This should never be invoked, we are born in fully
+                       // initialized state.
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       ig.Emit (OpCodes.Ldloc, b);
+                       ig.Emit (OpCodes.Conv_I);
+                       ig.Emit (OpCodes.Call, TypeManager.int_get_offset_to_string_data);
+                       ig.Emit (OpCodes.Add);
+               }
+       }
+       
+       //
+       // Implements the `stackalloc' keyword
+       //
+       public class StackAlloc : Expression {
+               Type otype;
+               Expression t;
+               Expression count;
+               
+               public StackAlloc (Expression type, Expression count, Location l)
+               {
+                       t = type;
+                       this.count = count;
+                       loc = l;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       count = count.Resolve (ec);
+                       if (count == null)
+                               return null;
+                       
+                       if (count.Type != TypeManager.int32_type){
+                               count = Convert.ImplicitConversionRequired (ec, count, TypeManager.int32_type, loc);
+                               if (count == null)
+                                       return null;
+                       }
+
+                       Constant c = count as Constant;
+                       if (c != null && c.IsNegative) {
+                               Report.Error (247, loc, "Cannot use a negative size with stackalloc");
+                               return null;
+                       }
+
+                       if (ec.CurrentBranching.InCatch () ||
+                           ec.CurrentBranching.InFinally (true)) {
+                               Error (255,
+                                             "stackalloc can not be used in a catch or finally block");
+                               return null;
+                       }
+
+                       TypeExpr texpr = t.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return null;
+
+                       otype = texpr.Type;
+
+                       if (!TypeManager.VerifyUnManaged (otype, loc))
+                               return null;
+
+                       type = TypeManager.GetPointerType (otype);
+                       eclass = ExprClass.Value;
+
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       int size = GetTypeSize (otype);
+                       ILGenerator ig = ec.ig;
+                               
+                       if (size == 0)
+                               ig.Emit (OpCodes.Sizeof, otype);
+                       else
+                               IntConstant.EmitInt (ig, size);
+                       count.Emit (ec);
+                       ig.Emit (OpCodes.Mul);
+                       ig.Emit (OpCodes.Localloc);
+               }
+       }
+}
diff --git a/mcs/bmcs/flowanalysis.cs b/mcs/bmcs/flowanalysis.cs
new file mode 100644 (file)
index 0000000..18f5714
--- /dev/null
@@ -0,0 +1,2307 @@
+//
+// flowanalyis.cs: The control flow analysis code
+//
+// Author:
+//   Martin Baulig (martin@ximian.com)
+//
+// (C) 2001, 2002, 2003 Ximian, Inc.
+//
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Diagnostics;
+
+namespace Mono.CSharp
+{
+       // <summary>
+       //   A new instance of this class is created every time a new block is resolved
+       //   and if there's branching in the block's control flow.
+       // </summary>
+       public abstract class FlowBranching
+       {
+               // <summary>
+               //   The type of a FlowBranching.
+               // </summary>
+               public enum BranchingType : byte {
+                       // Normal (conditional or toplevel) block.
+                       Block,
+
+                       // Conditional.
+                       Conditional,
+
+                       // A loop block.
+                       Loop,
+
+                       // Try/Catch block.
+                       Exception,
+
+                       // Switch block.
+                       Switch,
+
+                       // Switch section.
+                       SwitchSection
+               }
+
+               // <summary>
+               //   The type of one sibling of a branching.
+               // </summary>
+               public enum SiblingType : byte {
+                       Block,
+                       Conditional,
+                       SwitchSection,
+                       Try,
+                       Catch,
+                       Finally
+               }
+
+               // <summary>
+               //   This is used in the control flow analysis code to specify whether the
+               //   current code block may return to its enclosing block before reaching
+               //   its end.
+               // </summary>
+               public enum FlowReturns : byte {
+                       Undefined = 0,
+
+                       // It can never return.
+                       Never,
+
+                       // This means that the block contains a conditional return statement
+                       // somewhere.
+                       Sometimes,
+
+                       // The code always returns, ie. there's an unconditional return / break
+                       // statement in it.
+                       Always
+               }
+
+               public sealed class Reachability
+               {
+                       FlowReturns returns, breaks, throws, barrier;
+
+                       public FlowReturns Returns {
+                               get { return returns; }
+                       }
+                       public FlowReturns Breaks {
+                               get { return breaks; }
+                       }
+                       public FlowReturns Throws {
+                               get { return throws; }
+                       }
+                       public FlowReturns Barrier {
+                               get { return barrier; }
+                       }
+                       public Reachability (FlowReturns returns, FlowReturns breaks,
+                                            FlowReturns throws, FlowReturns barrier)
+                       {
+                               this.returns = returns;
+                               this.breaks = breaks;
+                               this.throws = throws;
+                               this.barrier = barrier;
+                       }
+
+                       public Reachability Clone ()
+                       {
+                               return new Reachability (returns, breaks, throws, barrier);
+                       }
+
+                       // <summary>
+                       //   Performs an `And' operation on the FlowReturns status
+                       //   (for instance, a block only returns Always if all its siblings
+                       //   always return).
+                       // </summary>
+                       public static FlowReturns AndFlowReturns (FlowReturns a, FlowReturns b)
+                       {
+                               if (a == FlowReturns.Undefined)
+                                       return b;
+
+                               switch (a) {
+                               case FlowReturns.Never:
+                                       if (b == FlowReturns.Never)
+                                               return FlowReturns.Never;
+                                       else
+                                               return FlowReturns.Sometimes;
+
+                               case FlowReturns.Sometimes:
+                                       return FlowReturns.Sometimes;
+
+                               case FlowReturns.Always:
+                                       if (b == FlowReturns.Always)
+                                               return FlowReturns.Always;
+                                       else
+                                               return FlowReturns.Sometimes;
+
+                               default:
+                                       throw new ArgumentException ();
+                               }
+                       }
+
+                       public static FlowReturns OrFlowReturns (FlowReturns a, FlowReturns b)
+                       {
+                               if (a == FlowReturns.Undefined)
+                                       return b;
+
+                               switch (a) {
+                               case FlowReturns.Never:
+                                       return b;
+
+                               case FlowReturns.Sometimes:
+                                       if (b == FlowReturns.Always)
+                                               return FlowReturns.Always;
+                                       else
+                                               return FlowReturns.Sometimes;
+
+                               case FlowReturns.Always:
+                                       return FlowReturns.Always;
+
+                               default:
+                                       throw new ArgumentException ();
+                               }
+                       }
+
+                       public static void And (ref Reachability a, Reachability b, bool do_break)
+                       {
+                               if (a == null) {
+                                       a = b.Clone ();
+                                       return;
+                               }
+
+                               //
+                               // `break' does not "break" in a Switch or a LoopBlock
+                               //
+                               bool a_breaks = do_break && a.AlwaysBreaks;
+                               bool b_breaks = do_break && b.AlwaysBreaks;
+
+                               bool a_has_barrier, b_has_barrier;
+                               if (do_break) {
+                                       //
+                                       // This is the normal case: the code following a barrier
+                                       // cannot be reached.
+                                       //
+                                       a_has_barrier = a.AlwaysHasBarrier;
+                                       b_has_barrier = b.AlwaysHasBarrier;
+                               } else {
+                                       //
+                                       // Special case for Switch and LoopBlocks: we can reach the
+                                       // code after the barrier via the `break'.
+                                       //
+                                       a_has_barrier = !a.AlwaysBreaks && a.AlwaysHasBarrier;
+                                       b_has_barrier = !b.AlwaysBreaks && b.AlwaysHasBarrier;
+                               }
+
+                               bool a_unreachable = a_breaks || a.AlwaysThrows || a_has_barrier;
+                               bool b_unreachable = b_breaks || b.AlwaysThrows || b_has_barrier;
+
+                               //
+                               // Do all code paths always return ?
+                               //
+                               if (a.AlwaysReturns) {
+                                       if (b.AlwaysReturns || b_unreachable)
+                                               a.returns = FlowReturns.Always;
+                                       else
+                                               a.returns = FlowReturns.Sometimes;
+                               } else if (b.AlwaysReturns) {
+                                       if (a.AlwaysReturns || a_unreachable)
+                                               a.returns = FlowReturns.Always;
+                                       else
+                                               a.returns = FlowReturns.Sometimes;
+                               } else if (!a.MayReturn) {
+                                       if (b.MayReturn)
+                                               a.returns = FlowReturns.Sometimes;
+                                       else
+                                               a.returns = FlowReturns.Never;
+                               } else if (!b.MayReturn) {
+                                       if (a.MayReturn)
+                                               a.returns = FlowReturns.Sometimes;
+                                       else
+                                               a.returns = FlowReturns.Never;
+                               }
+
+                               a.breaks = AndFlowReturns (a.breaks, b.breaks);
+                               a.throws = AndFlowReturns (a.throws, b.throws);
+                               a.barrier = AndFlowReturns (a.barrier, b.barrier);
+
+                               if (a_unreachable && b_unreachable)
+                                       a.barrier = FlowReturns.Always;
+                               else if (a_unreachable || b_unreachable)
+                                       a.barrier = FlowReturns.Sometimes;
+                               else
+                                       a.barrier = FlowReturns.Never;
+                       }
+
+                       public void Or (Reachability b)
+                       {
+                               returns = OrFlowReturns (returns, b.returns);
+                               breaks = OrFlowReturns (breaks, b.breaks);
+                               throws = OrFlowReturns (throws, b.throws);
+                               barrier = OrFlowReturns (barrier, b.barrier);
+                       }
+
+                       public static Reachability Never ()
+                       {
+                               return new Reachability (
+                                       FlowReturns.Never, FlowReturns.Never,
+                                       FlowReturns.Never, FlowReturns.Never);
+                       }
+
+                       public FlowReturns Reachable {
+                               get {
+                                       if ((returns == FlowReturns.Always) ||
+                                           (breaks == FlowReturns.Always) ||
+                                           (throws == FlowReturns.Always) ||
+                                           (barrier == FlowReturns.Always))
+                                               return FlowReturns.Never;
+                                       else if ((returns == FlowReturns.Never) &&
+                                                (breaks == FlowReturns.Never) &&
+                                                (throws == FlowReturns.Never) &&
+                                                (barrier == FlowReturns.Never))
+                                               return FlowReturns.Always;
+                               else
+                                               return FlowReturns.Sometimes;
+                               }
+                       }
+
+                       public bool AlwaysBreaks {
+                               get { return breaks == FlowReturns.Always; }
+                       }
+
+                       public bool MayBreak {
+                               get { return breaks != FlowReturns.Never; }
+                       }
+
+                       public bool AlwaysReturns {
+                               get { return returns == FlowReturns.Always; }
+                       }
+
+                       public bool MayReturn {
+                               get { return returns != FlowReturns.Never; }
+                       }
+
+                       public bool AlwaysThrows {
+                               get { return throws == FlowReturns.Always; }
+                       }
+
+                       public bool MayThrow {
+                               get { return throws != FlowReturns.Never; }
+                       }
+
+                       public bool AlwaysHasBarrier {
+                               get { return barrier == FlowReturns.Always; }
+                       }
+
+                       public bool MayHaveBarrier {
+                               get { return barrier != FlowReturns.Never; }
+                       }
+
+                       public bool IsUnreachable {
+                               get { return Reachable == FlowReturns.Never; }
+                       }
+
+                       public void SetReturns ()
+                       {
+                               returns = FlowReturns.Always;
+                       }
+
+                       public void SetReturnsSometimes ()
+                       {
+                               returns = FlowReturns.Sometimes;
+                       }
+
+                       public void SetBreaks ()
+                       {
+                               breaks = FlowReturns.Always;
+                       }
+
+                       public void ResetBreaks ()
+                       {
+                               breaks = FlowReturns.Never;
+                       }
+
+                       public void SetThrows ()
+                       {
+                               throws = FlowReturns.Always;
+                       }
+
+                       public void SetThrowsSometimes ()
+                       {
+                               throws = FlowReturns.Sometimes;
+                       }
+
+                       public void SetBarrier ()
+                       {
+                               barrier = FlowReturns.Always;
+                       }
+
+                       public void ResetBarrier ()
+                       {
+                               barrier = FlowReturns.Never;
+                       }
+
+                       static string ShortName (FlowReturns returns)
+                       {
+                               switch (returns) {
+                               case FlowReturns.Never:
+                                       return "N";
+                               case FlowReturns.Sometimes:
+                                       return "S";
+                               default:
+                                       return "A";
+                               }
+                       }
+
+                       public override string ToString ()
+                       {
+                               return String.Format ("[{0}:{1}:{2}:{3}:{4}]",
+                                                     ShortName (returns), ShortName (breaks),
+                                                     ShortName (throws), ShortName (barrier),
+                                                     ShortName (Reachable));
+                       }
+               }
+
+               public static FlowBranching CreateBranching (FlowBranching parent, BranchingType type, Block block, Location loc)
+               {
+                       switch (type) {
+                       case BranchingType.Exception:
+                               throw new InvalidOperationException ();
+
+                       case BranchingType.Switch:
+                               return new FlowBranchingBlock (parent, type, SiblingType.SwitchSection, block, loc);
+
+                       case BranchingType.SwitchSection:
+                               return new FlowBranchingBlock (parent, type, SiblingType.Block, block, loc);
+
+                       case BranchingType.Block:
+                               return new FlowBranchingBlock (parent, type, SiblingType.Block, block, loc);
+
+                       case BranchingType.Loop:
+                               return new FlowBranchingLoop (parent, block, loc);
+
+                       default:
+                               return new FlowBranchingBlock (parent, type, SiblingType.Conditional, block, loc);
+                       }
+               }
+
+               // <summary>
+               //   The type of this flow branching.
+               // </summary>
+               public readonly BranchingType Type;
+
+               // <summary>
+               //   The block this branching is contained in.  This may be null if it's not
+               //   a top-level block and it doesn't declare any local variables.
+               // </summary>
+               public readonly Block Block;
+
+               // <summary>
+               //   The parent of this branching or null if this is the top-block.
+               // </summary>
+               public readonly FlowBranching Parent;
+
+               // <summary>
+               //   Start-Location of this flow branching.
+               // </summary>
+               public readonly Location Location;
+
+               // <summary>
+               //   If this is an infinite loop.
+               // </summary>
+               public bool Infinite;
+
+               //
+               // Private
+               //
+               VariableMap param_map, local_map;
+
+               static int next_id = 0;
+               int id;
+
+               // <summary>
+               //   The vector contains a BitArray with information about which local variables
+               //   and parameters are already initialized at the current code position.
+               // </summary>
+               public class UsageVector {
+                       // <summary>
+                       //   The type of this branching.
+                       // </summary>
+                       public readonly SiblingType Type;
+
+                       // <summary>
+                       //   Start location of this branching.
+                       // </summary>
+                       public readonly Location Location;
+
+                       // <summary>
+                       //   This is only valid for SwitchSection, Try, Catch and Finally.
+                       // </summary>
+                       public readonly Block Block;
+
+                       // <summary>
+                       //   If this is true, then the usage vector has been modified and must be
+                       //   merged when we're done with this branching.
+                       // </summary>
+                       public bool IsDirty;
+
+                       // <summary>
+                       //   The number of parameters in this block.
+                       // </summary>
+                       public readonly int CountParameters;
+
+                       // <summary>
+                       //   The number of locals in this block.
+                       // </summary>
+                       public readonly int CountLocals;
+
+                       // <summary>
+                       //   If not null, then we inherit our state from this vector and do a
+                       //   copy-on-write.  If null, then we're the first sibling in a top-level
+                       //   block and inherit from the empty vector.
+                       // </summary>
+                       public readonly UsageVector InheritsFrom;
+
+                       // <summary>
+                       //   This is used to construct a list of UsageVector's.
+                       // </summary>
+                       public UsageVector Next;
+
+                       //
+                       // Private.
+                       //
+                       MyBitVector locals, parameters;
+                       Reachability reachability;
+
+                       static int next_id = 0;
+                       int id;
+
+                       //
+                       // Normally, you should not use any of these constructors.
+                       //
+                       public UsageVector (SiblingType type, UsageVector parent,
+                                           Block block, Location loc,
+                                           int num_params, int num_locals)
+                       {
+                               this.Type = type;
+                               this.Block = block;
+                               this.Location = loc;
+                               this.InheritsFrom = parent;
+                               this.CountParameters = num_params;
+                               this.CountLocals = num_locals;
+
+                               if (parent != null) {
+                                       if (num_locals > 0)
+                                       locals = new MyBitVector (parent.locals, CountLocals);
+                                       
+                                       if (num_params > 0)
+                                               parameters = new MyBitVector (parent.parameters, num_params);
+
+                                       reachability = parent.Reachability.Clone ();
+                               } else {
+                                       if (num_locals > 0)
+                                       locals = new MyBitVector (null, CountLocals);
+                                       
+                                       if (num_params > 0)
+                                               parameters = new MyBitVector (null, num_params);
+
+                                       reachability = Reachability.Never ();
+                               }
+
+                               id = ++next_id;
+                       }
+
+                       public UsageVector (SiblingType type, UsageVector parent,
+                                           Block block, Location loc)
+                               : this (type, parent, block, loc,
+                                       parent.CountParameters, parent.CountLocals)
+                       { }
+
+                       public UsageVector (MyBitVector parameters, MyBitVector locals,
+                                           Reachability reachability, Block block,
+                                           Location loc)
+                       {
+                               this.Type = SiblingType.Block;
+                               this.Location = loc;
+                               this.Block = block;
+
+                               this.reachability = reachability;
+                               this.parameters = parameters;
+                               this.locals = locals;
+
+                               id = ++next_id;
+                       }
+
+                       // <summary>
+                       //   This does a deep copy of the usage vector.
+                       // </summary>
+                       public UsageVector Clone ()
+                       {
+                               UsageVector retval = new UsageVector (
+                                       Type, null, Block, Location,
+                                       CountParameters, CountLocals);
+
+                               if (retval.locals != null)
+                               retval.locals = locals.Clone ();
+                               
+                               if (parameters != null)
+                                       retval.parameters = parameters.Clone ();
+                               
+                               retval.reachability = reachability.Clone ();
+
+                               return retval;
+                       }
+
+                       public bool IsAssigned (VariableInfo var)
+                       {
+                               if (!var.IsParameter && Reachability.IsUnreachable)
+                                       return true;
+
+                               return var.IsAssigned (var.IsParameter ? parameters : locals);
+                       }
+
+                       public void SetAssigned (VariableInfo var)
+                       {
+                               if (!var.IsParameter && Reachability.IsUnreachable)
+                                       return;
+
+                               IsDirty = true;
+                               var.SetAssigned (var.IsParameter ? parameters : locals);
+                       }
+
+                       public bool IsFieldAssigned (VariableInfo var, string name)
+                       {
+                               if (!var.IsParameter && Reachability.IsUnreachable)
+                                       return true;
+
+                               return var.IsFieldAssigned (var.IsParameter ? parameters : locals, name);
+                       }
+
+                       public void SetFieldAssigned (VariableInfo var, string name)
+                       {
+                               if (!var.IsParameter && Reachability.IsUnreachable)
+                                       return;
+
+                               IsDirty = true;
+                               var.SetFieldAssigned (var.IsParameter ? parameters : locals, name);
+                       }
+
+                       public Reachability Reachability {
+                               get {
+                                       return reachability;
+                               }
+                       }
+
+                       public void Return ()
+                       {
+                               if (!reachability.IsUnreachable) {
+                                       IsDirty = true;
+                                       reachability.SetReturns ();
+                               }
+                       }
+
+                       public void Break ()
+                       {
+                               if (!reachability.IsUnreachable) {
+                                       IsDirty = true;
+                                       reachability.SetBreaks ();
+                               }
+                       }
+
+                       public void Throw ()
+                       {
+                               if (!reachability.IsUnreachable) {
+                                       IsDirty = true;
+                                       reachability.SetThrows ();
+                               }
+                       }
+
+                       public void Goto ()
+                       {
+                               if (!reachability.IsUnreachable) {
+                                       IsDirty = true;
+                                       reachability.SetBarrier ();
+                               }
+                       }
+
+                       // <summary>
+                       //   Merges a child branching.
+                       // </summary>
+                       public UsageVector MergeChild (FlowBranching branching)
+                       {
+                               UsageVector result = branching.Merge ();
+
+                               Report.Debug (2, "  MERGING CHILD", this, branching, IsDirty,
+                                             result.ParameterVector, result.LocalVector,
+                                             result.Reachability, reachability, Type);
+
+                               Reachability new_r = result.Reachability;
+
+                               if (branching.Type == BranchingType.Loop) {
+                                       bool may_leave_loop = new_r.MayBreak;
+                                       new_r.ResetBreaks ();
+
+                                       if (branching.Infinite && !may_leave_loop) {
+                                               if (new_r.Returns == FlowReturns.Sometimes) {
+                                                       // If we're an infinite loop and do not break,
+                                                       // the code after the loop can never be reached.
+                                                       // However, if we may return from the loop,
+                                                       // then we do always return (or stay in the
+                                                       // loop forever).
+                                                       new_r.SetReturns ();
+                       }
+
+                                               new_r.SetBarrier ();
+                                       } else {
+                                               if (new_r.Returns == FlowReturns.Always) {
+                                                       // We're either finite or we may leave the loop.
+                                                       new_r.SetReturnsSometimes ();
+                       }
+                                               if (new_r.Throws == FlowReturns.Always) {
+                                                       // We're either finite or we may leave the loop.
+                                                       new_r.SetThrowsSometimes ();
+                                               }
+                       }
+                               } else if (branching.Type == BranchingType.Switch) {
+                                       if (new_r.MayBreak || new_r.MayReturn)
+                                               new_r.ResetBarrier ();
+
+                                       new_r.ResetBreaks ();
+                               }
+
+                               //
+                               // We've now either reached the point after the branching or we will
+                               // never get there since we always return or always throw an exception.
+                               //
+                               // If we can reach the point after the branching, mark all locals and
+                               // parameters as initialized which have been initialized in all branches
+                               // we need to look at (see above).
+                               //
+
+                               if ((Type == SiblingType.SwitchSection) && !new_r.IsUnreachable) {
+                                       Report.Error (163, Location,
+                                                     "Control cannot fall through from one " +
+                                                             "case label to another");
+                                       return result;
+                                       }
+
+                               if (locals != null && result.LocalVector != null)
+                                       locals.Or (result.LocalVector);
+
+                               if (result.ParameterVector != null)
+                                       parameters.Or (result.ParameterVector);
+
+                               reachability.Or (new_r);
+
+                               Report.Debug (2, "  MERGING CHILD DONE", this, result,
+                                             new_r, reachability);
+
+                               IsDirty = true;
+
+                               return result;
+                               }
+
+                       protected void MergeFinally (FlowBranching branching, UsageVector f_origins,
+                                                    MyBitVector f_params)
+                       {
+                               for (UsageVector vector = f_origins; vector != null; vector = vector.Next) {
+                                       MyBitVector temp_params = f_params.Clone ();
+                                       temp_params.Or (vector.Parameters);
+                               }
+                       }
+
+                       public void MergeFinally (FlowBranching branching, UsageVector f_vector,
+                                                 UsageVector f_origins)
+                       {
+                               if (parameters != null) {
+                                       if (f_vector != null) {
+                                               MergeFinally (branching, f_origins, f_vector.Parameters);
+                                               MyBitVector.Or (ref parameters, f_vector.ParameterVector);
+                                       } else
+                                               MergeFinally (branching, f_origins, parameters);
+                               }
+
+                               if (f_vector != null && f_vector.LocalVector != null)
+                                       MyBitVector.Or (ref locals, f_vector.LocalVector);
+                       }
+
+                       // <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
+                       //   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
+                       //   the goto in line 4:
+                       //
+                       //      1     int a;
+                       //
+                       //      3     if (something)
+                       //      4        goto World;
+                       //
+                       //      6     a = 5;
+                       //
+                       //      7  World:
+                       //      8     Console.WriteLine (a);
+                       //
+                       // </summary>
+                       public void MergeJumpOrigins (UsageVector o_vectors)
+                       {
+                               Report.Debug (1, "  MERGING JUMP ORIGINS", this);
+
+                               reachability = Reachability.Never ();
+
+                               if (o_vectors == null) {
+                                       reachability.SetBarrier ();
+                                       return;
+                               }
+
+                               bool first = true;
+
+                               for (UsageVector vector = o_vectors; vector != null;
+                                    vector = vector.Next) {
+                                       Report.Debug (1, "  MERGING JUMP ORIGIN", vector);
+
+                                       if (first) {
+                                               if (locals != null && vector.Locals != null)
+                                               locals.Or (vector.locals);
+                                               
+                                               if (parameters != null)
+                                                       parameters.Or (vector.parameters);
+                                               first = false;
+                                       } else {
+                                               if (locals != null && vector.Locals != null)
+                                       locals.And (vector.locals);
+                                       if (parameters != null)
+                                               parameters.And (vector.parameters);
+                               }
+
+                                       Reachability.And (ref reachability, vector.Reachability, true);
+                               }
+
+                               Report.Debug (1, "  MERGING JUMP ORIGINS DONE", this);
+                       }
+
+                       // <summary>
+                       //   This is used at the beginning of a finally block if there were
+                       //   any return statements in the try block or one of the catch blocks.
+                       // </summary>
+                       public void MergeFinallyOrigins (UsageVector f_origins)
+                       {
+                               Report.Debug (1, "  MERGING FINALLY ORIGIN", this);
+
+                               reachability = Reachability.Never ();
+
+                               for (UsageVector vector = f_origins; vector != null; vector = vector.Next) {
+                                       Report.Debug (1, "  MERGING FINALLY ORIGIN", vector);
+
+                                       if (parameters != null)
+                                               parameters.And (vector.parameters);
+
+                                       Reachability.And (ref reachability, vector.Reachability, true);
+                               }
+
+                               Report.Debug (1, "  MERGING FINALLY ORIGIN DONE", this);
+                       }
+
+                       public void MergeBreakOrigins (UsageVector o_vectors)
+                       {
+                               Report.Debug (1, "  MERGING BREAK ORIGINS", this);
+
+                               if (o_vectors == null)
+                                       return;
+
+                               bool first = true;
+
+                               for (UsageVector vector = o_vectors; vector != null;
+                                    vector = vector.Next) {
+                                       Report.Debug (1, "    MERGING BREAK ORIGIN", vector);
+
+                                       if (first) {
+                                               if (locals != null && vector.Locals != null)
+                                                       locals.Or (vector.locals);
+                                               
+                                               if (parameters != null)
+                                                       parameters.Or (vector.parameters);
+                                               first = false;
+                                       } else {
+                                               if (locals != null && vector.Locals != null)
+                                                       locals.And (vector.locals);
+                                               if (parameters != null)
+                                                       parameters.And (vector.parameters);
+                                       }
+                               }
+
+                               Report.Debug (1, "  MERGING BREAK ORIGINS DONE", this);
+                       }
+
+                       public void CheckOutParameters (FlowBranching branching)
+                       {
+                               if (parameters != null)
+                                       branching.CheckOutParameters (parameters, branching.Location);
+                       }
+
+                       // <summary>
+                       //   Performs an `or' operation on the locals and the parameters.
+                       // </summary>
+                       public void Or (UsageVector new_vector)
+                       {
+                               IsDirty = true;
+                               locals.Or (new_vector.locals);
+                               if (parameters != null)
+                                       parameters.Or (new_vector.parameters);
+                       }
+
+                       // <summary>
+                       //   Performs an `and' operation on the locals.
+                       // </summary>
+                       public void AndLocals (UsageVector new_vector)
+                       {
+                               IsDirty = true;
+                               locals.And (new_vector.locals);
+                       }
+
+                       public bool HasParameters {
+                               get {
+                                       return parameters != null;
+                               }
+                       }
+
+                       public bool HasLocals {
+                               get {
+                                       return locals != null;
+                               }
+                       }
+
+                       // <summary>
+                       //   Returns a deep copy of the parameters.
+                       // </summary>
+                       public MyBitVector Parameters {
+                               get {
+                                       if (parameters != null)
+                                               return parameters.Clone ();
+                                       else
+                                               return null;
+                               }
+                       }
+
+                       // <summary>
+                       //   Returns a deep copy of the locals.
+                       // </summary>
+                       public MyBitVector Locals {
+                               get {
+                                       if (locals != null)
+                                       return locals.Clone ();
+                                       else
+                                               return null;
+                               }
+                       }
+
+                       public MyBitVector ParameterVector {
+                               get {
+                                       return parameters;
+                               }
+                       }
+
+                       public MyBitVector LocalVector {
+                               get {
+                                       return locals;
+                               }
+                       }
+
+                       //
+                       // Debugging stuff.
+                       //
+
+                       public override string ToString ()
+                       {
+                               StringBuilder sb = new StringBuilder ();
+
+                               sb.Append ("Vector (");
+                               sb.Append (Type);
+                               sb.Append (",");
+                               sb.Append (id);
+                               sb.Append (",");
+                               sb.Append (IsDirty);
+                               sb.Append (",");
+                               sb.Append (reachability);
+                               if (parameters != null) {
+                                       sb.Append (" - ");
+                                       sb.Append (parameters);
+                               }
+                               sb.Append (" - ");
+                               sb.Append (locals);
+                               sb.Append (")");
+
+                               return sb.ToString ();
+                       }
+               }
+
+               // <summary>
+               //   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>
+               protected FlowBranching (FlowBranching parent, BranchingType type, SiblingType stype,
+                                        Block block, Location loc)
+               {
+                       Parent = parent;
+                       Block = block;
+                       Location = loc;
+                       Type = type;
+                       id = ++next_id;
+
+                       UsageVector vector;
+                       if (Block != null) {
+                               param_map = Block.ParameterMap;
+                               local_map = Block.LocalMap;
+
+                               UsageVector parent_vector = parent != null ? parent.CurrentUsageVector : null;
+                               vector = new UsageVector (
+                                       stype, parent_vector, Block, loc,
+                                       param_map.Length, local_map.Length);
+                       } else {
+                               param_map = Parent.param_map;
+                               local_map = Parent.local_map;
+                               vector = new UsageVector (
+                                       stype, Parent.CurrentUsageVector, null, loc);
+                       }
+
+                       AddSibling (vector);
+               }
+
+               public abstract UsageVector CurrentUsageVector {
+                       get;
+               }                               
+
+               // <summary>
+               //   Creates a sibling of the current usage vector.
+               // </summary>
+               public virtual void CreateSibling (Block block, SiblingType type)
+               {
+                       UsageVector vector = new UsageVector (
+                               type, Parent.CurrentUsageVector, block, Location);
+                       AddSibling (vector);
+
+                       Report.Debug (1, "  CREATED SIBLING", CurrentUsageVector);
+               }
+
+               public void CreateSibling ()
+               {
+                       CreateSibling (null, SiblingType.Conditional);
+               }
+
+               protected abstract void AddSibling (UsageVector uv);
+
+               public virtual LabeledStatement LookupLabel (string name, Location loc)
+               {
+                       if (Parent != null)
+                               return Parent.LookupLabel (name, loc);
+
+                       Report.Error (
+                               159, loc,
+                               "No such label `" + name + "' in this scope");
+                       return null;
+               }
+
+               public abstract void Label (UsageVector origin_vectors);
+
+               // <summary>
+               //   Check whether all `out' parameters have been assigned.
+               // </summary>
+               public void CheckOutParameters (MyBitVector parameters, Location loc)
+               {
+                       for (int i = 0; i < param_map.Count; i++) {
+                               VariableInfo var = param_map [i];
+
+                               if (var == null)
+                                       continue;
+
+                               if (var.IsAssigned (parameters))
+                                       continue;
+
+                               Report.Error (177, loc, "The out parameter `" +
+                                             var.Name + "' must be " +
+                                             "assigned before control leaves the current method.");
+                       }
+               }
+
+               protected UsageVector Merge (UsageVector sibling_list)
+                       {
+                       if (sibling_list.Next == null)
+                               return sibling_list;
+
+                       MyBitVector locals = null;
+                       MyBitVector parameters = null;
+
+                       Reachability reachability = null;
+
+                       Report.Debug (2, "  MERGING SIBLINGS", this, Name);
+
+                       for (UsageVector child = sibling_list; child != null; child = child.Next) {
+                               bool do_break = (Type != BranchingType.Switch) &&
+                                       (Type != BranchingType.Loop);
+                               
+                               Report.Debug (2, "    MERGING SIBLING   ", child,
+                                             child.ParameterVector, child.LocalVector,
+                                             reachability, child.Reachability, do_break);
+
+                               Reachability.And (ref reachability, child.Reachability, do_break);
+                                       
+                               // A local variable is initialized after a flow branching if it
+                               // has been initialized in all its branches which do neither
+                               // always return or always throw an exception.
+                               //
+                               // If a branch may return, but does not always return, then we
+                               // can treat it like a never-returning branch here: control will
+                               // only reach the code position after the branching if we did not
+                               // return here.
+                               //
+                               // It's important to distinguish between always and sometimes
+                               // returning branches here:
+                               //
+                               //    1   int a;
+                               //    2   if (something) {
+                               //    3      return;
+                               //    4      a = 5;
+                               //    5   }
+                               //    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
+                               // uninitialized in line 6.
+                               //
+                               // On the other hand, the following is allowed:
+                               //
+                               //    1   int a;
+                               //    2   if (something)
+                               //    3      a = 5;
+                               //    4   else
+                               //    5      return;
+                               //    6   Console.WriteLine (a);
+                               //
+                               // Here, `a' is initialized in line 3 and we must not look at
+                               // line 5 since it always returns.
+                               // 
+                               bool do_break_2 = (child.Type != SiblingType.Block) &&
+                                       (child.Type != SiblingType.SwitchSection);
+                               bool always_throws = (child.Type != SiblingType.Try) &&
+                                       child.Reachability.AlwaysThrows;
+                               bool unreachable = always_throws ||
+                                       (do_break_2 && child.Reachability.AlwaysBreaks) ||
+                                       child.Reachability.AlwaysReturns ||
+                                       child.Reachability.AlwaysHasBarrier;
+
+                               Report.Debug (2, "    MERGING SIBLING #1", reachability,
+                                             Type, child.Type, child.Reachability.IsUnreachable,
+                                             do_break_2, always_throws, unreachable);
+
+                               if (!unreachable && (child.LocalVector != null))
+                                       MyBitVector.And (ref locals, child.LocalVector);
+
+                               // An `out' parameter must be assigned in all branches which do
+                               // not always throw an exception.
+                               if ((child.ParameterVector != null) && !child.Reachability.AlwaysThrows)
+                                       MyBitVector.And (ref parameters, child.ParameterVector);
+
+                               Report.Debug (2, "    MERGING SIBLING #2", parameters, locals);
+                       }
+
+                       if (reachability == null)
+                               reachability = Reachability.Never ();
+
+                       Report.Debug (2, "  MERGING SIBLINGS DONE", parameters, locals,
+                                     reachability, Infinite);
+
+                       return new UsageVector (
+                               parameters, locals, reachability, null, Location);
+               }
+
+               protected abstract UsageVector Merge ();
+
+               // <summary>
+               //   Merge a child branching.
+               // </summary>
+               public UsageVector MergeChild (FlowBranching child)
+               {
+                       return CurrentUsageVector.MergeChild (child);
+               }
+
+               // <summary>
+               //   Does the toplevel merging.
+               // </summary>
+               public Reachability MergeTopBlock ()
+               {
+                       if ((Type != BranchingType.Block) || (Block == null))
+                               throw new NotSupportedException ();
+
+                       UsageVector vector = new UsageVector (
+                               SiblingType.Conditional, null, Block, Location,
+                               param_map.Length, local_map.Length);
+
+                       UsageVector result = vector.MergeChild (this);
+
+                       Report.Debug (4, "MERGE TOP BLOCK", Location, vector, result.Reachability);
+
+                       if ((vector.Reachability.Throws != FlowReturns.Always) &&
+                           (vector.Reachability.Barrier != FlowReturns.Always))
+                               CheckOutParameters (vector.Parameters, Location);
+
+                       return result.Reachability;
+               }
+
+               //
+               // Checks whether we're in a `try' block.
+               //
+               public virtual bool InTryOrCatch (bool is_return)
+               {
+                       if ((Block != null) && Block.IsDestructor)
+                               return true;
+                       else if (!is_return &&
+                           ((Type == BranchingType.Loop) || (Type == BranchingType.Switch)))
+                               return false;
+                       else if (Parent != null)
+                               return Parent.InTryOrCatch (is_return);
+                       else
+                               return false;
+               }
+
+               //
+               // Checks whether we're in a `catch' block.
+               //
+               public virtual bool InCatch ()
+               {
+                       if (Parent != null)
+                               return Parent.InCatch ();
+                       else
+                               return false;
+               }
+
+               //
+               // Checks whether we're in a `finally' block.
+               //
+               public virtual bool InFinally (bool is_return)
+               {
+                       if (!is_return &&
+                           ((Type == BranchingType.Loop) || (Type == BranchingType.Switch)))
+                               return false;
+                       else if (Parent != null)
+                               return Parent.InFinally (is_return);
+                       else
+                               return false;
+               }
+
+               public virtual bool InLoop ()
+               {
+                       if (Type == BranchingType.Loop)
+                               return true;
+                       else if (Parent != null)
+                               return Parent.InLoop ();
+                       else
+                               return false;
+               }
+
+               public virtual bool InSwitch ()
+               {
+                       if (Type == BranchingType.Switch)
+                               return true;
+                       else if (Parent != null)
+                               return Parent.InSwitch ();
+                       else
+                               return false;
+               }
+
+               public virtual bool BreakCrossesTryCatchBoundary ()
+               {
+                       if ((Type == BranchingType.Loop) || (Type == BranchingType.Switch))
+                               return false;
+                       else if (Parent != null)
+                               return Parent.BreakCrossesTryCatchBoundary ();
+                       else
+                               return false;
+               }
+
+               public virtual void AddFinallyVector (UsageVector vector)
+               {
+                       if (Parent != null)
+                               Parent.AddFinallyVector (vector);
+                       else if ((Block == null) || !Block.IsDestructor)
+                               throw new NotSupportedException ();
+               }
+
+               public virtual void AddBreakVector (UsageVector vector)
+               {
+                       if (Parent != null)
+                               Parent.AddBreakVector (vector);
+                       else if ((Block == null) || !Block.IsDestructor)
+                               throw new NotSupportedException ();
+               }
+
+               public virtual void StealFinallyClauses (ref ArrayList list)
+               {
+                       if (Parent != null)
+                               Parent.StealFinallyClauses (ref list);
+               }
+
+               public bool IsAssigned (VariableInfo vi)
+               {
+                       return CurrentUsageVector.IsAssigned (vi);
+               }
+
+               public bool IsFieldAssigned (VariableInfo vi, string field_name)
+               {
+                       if (CurrentUsageVector.IsAssigned (vi))
+                               return true;
+
+                       return CurrentUsageVector.IsFieldAssigned (vi, field_name);
+               }
+
+               public void SetAssigned (VariableInfo vi)
+               {
+                       CurrentUsageVector.SetAssigned (vi);
+               }
+
+               public void SetFieldAssigned (VariableInfo vi, string name)
+               {
+                       CurrentUsageVector.SetFieldAssigned (vi, name);
+               }
+
+               public override string ToString ()
+               {
+                       StringBuilder sb = new StringBuilder ();
+                       sb.Append (GetType ());
+                       sb.Append (" (");
+
+                       sb.Append (id);
+                       sb.Append (",");
+                       sb.Append (Type);
+                       if (Block != null) {
+                               sb.Append (" - ");
+                               sb.Append (Block.ID);
+                               sb.Append (" - ");
+                               sb.Append (Block.StartLocation);
+                       }
+                       sb.Append (" - ");
+                       // sb.Append (Siblings.Length);
+                       // sb.Append (" - ");
+                       sb.Append (CurrentUsageVector);
+                       sb.Append (")");
+                       return sb.ToString ();
+               }
+
+               public string Name {
+                       get {
+                               return String.Format ("{0} ({1}:{2}:{3})",
+                                                     GetType (), id, Type, Location);
+                       }
+               }
+       }
+
+       public class FlowBranchingBlock : FlowBranching
+       {
+               UsageVector sibling_list = null;
+
+               public FlowBranchingBlock (FlowBranching parent, BranchingType type,
+                                          SiblingType stype, Block block, Location loc)
+                       : base (parent, type, stype, block, loc)
+               { }
+
+               public override UsageVector CurrentUsageVector {
+                       get { return sibling_list; }
+               }
+
+               protected override void AddSibling (UsageVector sibling)
+               {
+                       sibling.Next = sibling_list;
+                       sibling_list = sibling;
+               }
+
+               public override LabeledStatement LookupLabel (string name, Location loc)
+               {
+                       if (Block == null)
+                               return base.LookupLabel (name, loc);
+
+                       LabeledStatement s = Block.LookupLabel (name);
+                       if (s != null)
+                               return s;
+
+                       return base.LookupLabel (name, loc);
+               }
+
+               public override void Label (UsageVector origin_vectors)
+               {
+                       if (!CurrentUsageVector.Reachability.IsUnreachable) {
+                               UsageVector vector = CurrentUsageVector.Clone ();
+                               vector.Next = origin_vectors;
+                               origin_vectors = vector;
+               }
+
+                       CurrentUsageVector.MergeJumpOrigins (origin_vectors);
+               }
+
+               protected override UsageVector Merge ()
+               {
+                       return Merge (sibling_list);
+               }
+       }
+
+       public class FlowBranchingLoop : FlowBranchingBlock
+       {
+               UsageVector break_origins;
+
+               public FlowBranchingLoop (FlowBranching parent, Block block, Location loc)
+                       : base (parent, BranchingType.Loop, SiblingType.Conditional, block, loc)
+               { }
+
+               public override void AddBreakVector (UsageVector vector)
+               {
+                       vector = vector.Clone ();
+                       vector.Next = break_origins;
+                       break_origins = vector;
+               }
+
+               protected override UsageVector Merge ()
+               {
+                       UsageVector vector = base.Merge ();
+
+                       vector.MergeBreakOrigins (break_origins);
+
+                       return vector;
+               }
+       }
+
+       public class FlowBranchingException : FlowBranching
+       {
+               ExceptionStatement stmt;
+               UsageVector current_vector;
+               UsageVector catch_vectors;
+               UsageVector finally_vector;
+               UsageVector finally_origins;
+               bool emit_finally;
+               bool in_try;
+
+               public FlowBranchingException (FlowBranching parent,
+                                              ExceptionStatement stmt)
+                       : base (parent, BranchingType.Exception, SiblingType.Try,
+                               null, stmt.loc)
+               {
+                       this.stmt = stmt;
+                       this.emit_finally = true;
+               }
+
+               protected override void AddSibling (UsageVector sibling)
+               {
+                       if (sibling.Type == SiblingType.Try) {
+                               sibling.Next = catch_vectors;
+                               catch_vectors = sibling;
+                               in_try = true;
+                       } else if (sibling.Type == SiblingType.Catch) {
+                               sibling.Next = catch_vectors;
+                               catch_vectors = sibling;
+                               in_try = false;
+                       } else if (sibling.Type == SiblingType.Finally) {
+                               sibling.MergeFinallyOrigins (finally_origins);
+                               finally_vector = sibling;
+                               in_try = false;
+                       } else
+                               throw new InvalidOperationException ();
+
+                       current_vector = sibling;
+               }
+
+               public override UsageVector CurrentUsageVector {
+                       get { return current_vector; }
+               }
+
+               public override bool InTryOrCatch (bool is_return)
+               {
+                       return finally_vector == null;
+               }
+
+               public override bool InCatch ()
+               {
+                       return !in_try && (finally_vector == null);
+               }
+
+               public override bool InFinally (bool is_return)
+               {
+                       return finally_vector != null;
+               }
+
+               public override bool BreakCrossesTryCatchBoundary ()
+               {
+                       return true;
+               }
+
+               public override void AddFinallyVector (UsageVector vector)
+               {
+                       vector = vector.Clone ();
+                       vector.Next = finally_origins;
+                       finally_origins = vector;
+               }
+
+               public override void StealFinallyClauses (ref ArrayList list)
+               {
+                       if (list == null)
+                               list = new ArrayList ();
+                       list.Add (stmt);
+                       emit_finally = false;
+                       base.StealFinallyClauses (ref list);
+               }
+
+               public bool EmitFinally {
+                       get { return emit_finally; }
+               }
+
+               public override LabeledStatement LookupLabel (string name, Location loc)
+               {
+                       if (current_vector.Block == null)
+                               return base.LookupLabel (name, loc);
+
+                       LabeledStatement s = current_vector.Block.LookupLabel (name);
+                       if (s != null)
+                               return s;
+
+                       if (finally_vector != null) {
+                               Report.Error (
+                                       157, loc, "Control can not leave the body " +
+                                       "of the finally block");
+                               return null;
+                       }
+
+                       return base.LookupLabel (name, loc);
+               }
+
+               public override void Label (UsageVector origin_vectors)
+               {
+                       CurrentUsageVector.MergeJumpOrigins (origin_vectors);
+               }
+
+               protected override UsageVector Merge ()
+               {
+                       UsageVector vector = Merge (catch_vectors);
+
+                       vector.MergeFinally (this, finally_vector, finally_origins);
+
+                       return vector;
+               }
+       }
+
+       // <summary>
+       //   This is used by the flow analysis code to keep track of the type of local variables
+       //   and variables.
+       //
+       //   The flow code uses a BitVector to keep track of whether a variable has been assigned
+       //   or not.  This is easy for fundamental types (int, char etc.) or reference types since
+       //   you can only assign the whole variable as such.
+       //
+       //   For structs, we also need to keep track of all its fields.  To do this, we allocate one
+       //   bit for the struct itself (it's used if you assign/access the whole struct) followed by
+       //   one bit for each of its fields.
+       //
+       //   This class computes this `layout' for each type.
+       // </summary>
+       public class TypeInfo
+       {
+               public readonly Type Type;
+
+               // <summary>
+               //   Total number of bits a variable of this type consumes in the flow vector.
+               // </summary>
+               public readonly int TotalLength;
+
+               // <summary>
+               //   Number of bits the simple fields of a variable of this type consume
+               //   in the flow vector.
+               // </summary>
+               public readonly int Length;
+
+               // <summary>
+               //   This is only used by sub-structs.
+               // </summary>
+               public readonly int Offset;
+
+               // <summary>
+               //   If this is a struct.
+               // </summary>
+               public readonly bool IsStruct;       
+
+               // <summary>
+               //   If this is a struct, all fields which are structs theirselves.
+               // </summary>
+               public TypeInfo[] SubStructInfo;
+
+               protected readonly StructInfo struct_info;
+               private static Hashtable type_hash = new Hashtable ();
+
+               public static TypeInfo GetTypeInfo (Type type)
+               {
+                       TypeInfo info = (TypeInfo) type_hash [type];
+                       if (info != null)
+                               return info;
+
+                       info = new TypeInfo (type);
+                       type_hash.Add (type, info);
+                       return info;
+               }
+
+               public static TypeInfo GetTypeInfo (TypeContainer tc)
+               {
+                       TypeInfo info = (TypeInfo) type_hash [tc.TypeBuilder];
+                       if (info != null)
+                               return info;
+
+                       info = new TypeInfo (tc);
+                       type_hash.Add (tc.TypeBuilder, info);
+                       return info;
+               }
+
+               private TypeInfo (Type type)
+               {
+                       this.Type = type;
+
+                       struct_info = StructInfo.GetStructInfo (type);
+                       if (struct_info != null) {
+                               Length = struct_info.Length;
+                               TotalLength = struct_info.TotalLength;
+                               SubStructInfo = struct_info.StructFields;
+                               IsStruct = true;
+                       } else {
+                               Length = 0;
+                               TotalLength = 1;
+                               IsStruct = false;
+                       }
+               }
+
+               private TypeInfo (TypeContainer tc)
+               {
+                       this.Type = tc.TypeBuilder;
+
+                       struct_info = StructInfo.GetStructInfo (tc);
+                       if (struct_info != null) {
+                               Length = struct_info.Length;
+                               TotalLength = struct_info.TotalLength;
+                               SubStructInfo = struct_info.StructFields;
+                               IsStruct = true;
+                       } else {
+                               Length = 0;
+                               TotalLength = 1;
+                               IsStruct = false;
+                       }
+               }
+
+               protected TypeInfo (StructInfo struct_info, int offset)
+               {
+                       this.struct_info = struct_info;
+                       this.Offset = offset;
+                       this.Length = struct_info.Length;
+                       this.TotalLength = struct_info.TotalLength;
+                       this.SubStructInfo = struct_info.StructFields;
+                       this.Type = struct_info.Type;
+                       this.IsStruct = true;
+               }
+
+               public int GetFieldIndex (string name)
+               {
+                       if (struct_info == null)
+                               return 0;
+
+                       return struct_info [name];
+               }
+
+               public TypeInfo GetSubStruct (string name)
+               {
+                       if (struct_info == null)
+                               return null;
+
+                       return struct_info.GetStructField (name);
+               }
+
+               // <summary>
+               //   A struct's constructor must always assign all fields.
+               //   This method checks whether it actually does so.
+               // </summary>
+               public bool IsFullyInitialized (FlowBranching branching, VariableInfo vi, Location loc)
+               {
+                       if (struct_info == null)
+                               return true;
+
+                       bool ok = true;
+                       for (int i = 0; i < struct_info.Count; i++) {
+                               FieldInfo field = struct_info.Fields [i];
+
+                               if (!branching.IsFieldAssigned (vi, field.Name)) {
+                                       Report.Error (171, loc,
+                                                     "Field `" + TypeManager.CSharpName (Type) +
+                                                     "." + field.Name + "' must be fully initialized " +
+                                                     "before control leaves the constructor");
+                                       ok = false;
+                               }
+                       }
+
+                       return ok;
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("TypeInfo ({0}:{1}:{2}:{3})",
+                                             Type, Offset, Length, TotalLength);
+               }
+
+               protected class StructInfo {
+                       public readonly Type Type;
+                       public readonly FieldInfo[] Fields;
+                       public readonly TypeInfo[] StructFields;
+                       public readonly int Count;
+                       public readonly int CountPublic;
+                       public readonly int CountNonPublic;
+                       public readonly int Length;
+                       public readonly int TotalLength;
+                       public readonly bool HasStructFields;
+
+                       private static Hashtable field_type_hash = new Hashtable ();
+                       private Hashtable struct_field_hash;
+                       private Hashtable field_hash;
+
+                       protected bool InTransit = false;
+
+                       // Private constructor.  To save memory usage, we only need to create one instance
+                       // of this class per struct type.
+                       private StructInfo (Type type)
+                       {
+                               this.Type = type;
+
+                               field_type_hash.Add (type, this);
+
+                               if (type is TypeBuilder) {
+                                       TypeContainer tc = TypeManager.LookupTypeContainer (type);
+
+                                       ArrayList fields = tc.Fields;
+
+                                       ArrayList public_fields = new ArrayList ();
+                                       ArrayList non_public_fields = new ArrayList ();
+
+                                       if (fields != null) {
+                                               foreach (Field field in fields) {
+                                                       if ((field.ModFlags & Modifiers.STATIC) != 0)
+                                                               continue;
+                                                       if ((field.ModFlags & Modifiers.PUBLIC) != 0)
+                                                               public_fields.Add (field.FieldBuilder);
+                                                       else
+                                                               non_public_fields.Add (field.FieldBuilder);
+                                               }
+                                       }
+
+                                       CountPublic = public_fields.Count;
+                                       CountNonPublic = non_public_fields.Count;
+                                       Count = CountPublic + CountNonPublic;
+
+                                       Fields = new FieldInfo [Count];
+                                       public_fields.CopyTo (Fields, 0);
+                                       non_public_fields.CopyTo (Fields, CountPublic);
+                               } else if (type is GenericTypeParameterBuilder) {
+                                       CountPublic = CountNonPublic = Count = 0;
+
+                                       Fields = new FieldInfo [0];
+                               } else {
+                                       FieldInfo[] public_fields = type.GetFields (
+                                               BindingFlags.Instance|BindingFlags.Public);
+                                       FieldInfo[] non_public_fields = type.GetFields (
+                                               BindingFlags.Instance|BindingFlags.NonPublic);
+
+                                       CountPublic = public_fields.Length;
+                                       CountNonPublic = non_public_fields.Length;
+                                       Count = CountPublic + CountNonPublic;
+
+                                       Fields = new FieldInfo [Count];
+                                       public_fields.CopyTo (Fields, 0);
+                                       non_public_fields.CopyTo (Fields, CountPublic);
+                               }
+
+                               struct_field_hash = new Hashtable ();
+                               field_hash = new Hashtable ();
+
+                               Length = 0;
+                               StructFields = new TypeInfo [Count];
+                               StructInfo[] sinfo = new StructInfo [Count];
+
+                               InTransit = true;
+
+                               for (int i = 0; i < Count; i++) {
+                                       FieldInfo field = (FieldInfo) Fields [i];
+
+                                       sinfo [i] = GetStructInfo (field.FieldType);
+                                       if (sinfo [i] == null)
+                                               field_hash.Add (field.Name, ++Length);
+                                       else if (sinfo [i].InTransit) {
+                                               Report.Error (523, String.Format (
+                                                                     "Struct member '{0}.{1}' of type '{2}' causes " +
+                                                                     "a cycle in the structure layout",
+                                                                     type, field.Name, sinfo [i].Type));
+                                               sinfo [i] = null;
+                                               return;
+                                       }
+                               }
+
+                               InTransit = false;
+
+                               TotalLength = Length + 1;
+                               for (int i = 0; i < Count; i++) {
+                                       FieldInfo field = (FieldInfo) Fields [i];
+
+                                       if (sinfo [i] == null)
+                                               continue;
+
+                                       field_hash.Add (field.Name, TotalLength);
+
+                                       HasStructFields = true;
+                                       StructFields [i] = new TypeInfo (sinfo [i], TotalLength);
+                                       struct_field_hash.Add (field.Name, StructFields [i]);
+                                       TotalLength += sinfo [i].TotalLength;
+                               }
+                       }
+
+                       public int this [string name] {
+                               get {
+                                       if (field_hash.Contains (name))
+                                               return (int) field_hash [name];
+                                       else
+                                               return 0;
+                               }
+                       }
+
+                       public TypeInfo GetStructField (string name)
+                       {
+                               return (TypeInfo) struct_field_hash [name];
+                       }
+
+                       public static StructInfo GetStructInfo (Type type)
+                       {
+                               if (!TypeManager.IsValueType (type) || TypeManager.IsEnumType (type) ||
+                                   TypeManager.IsBuiltinType (type))
+                                       return null;
+
+                               StructInfo info = (StructInfo) field_type_hash [type];
+                               if (info != null)
+                                       return info;
+
+                               return new StructInfo (type);
+                       }
+
+                       public static StructInfo GetStructInfo (TypeContainer tc)
+                       {
+                               StructInfo info = (StructInfo) field_type_hash [tc.TypeBuilder];
+                               if (info != null)
+                                       return info;
+
+                               return new StructInfo (tc.TypeBuilder);
+                       }
+               }
+       }
+
+       // <summary>
+       //   This is used by the flow analysis code to store information about a single local variable
+       //   or parameter.  Depending on the variable's type, we need to allocate one or more elements
+       //   in the BitVector - if it's a fundamental or reference type, we just need to know whether
+       //   it has been assigned or not, but for structs, we need this information for each of its fields.
+       // </summary>
+       public class VariableInfo {
+               public readonly string Name;
+               public readonly TypeInfo TypeInfo;
+
+               // <summary>
+               //   The bit offset of this variable in the flow vector.
+               // </summary>
+               public readonly int Offset;
+
+               // <summary>
+               //   The number of bits this variable needs in the flow vector.
+               //   The first bit always specifies whether the variable as such has been assigned while
+               //   the remaining bits contain this information for each of a struct's fields.
+               // </summary>
+               public readonly int Length;
+
+               // <summary>
+               //   If this is a parameter of local variable.
+               // </summary>
+               public readonly bool IsParameter;
+
+               public readonly LocalInfo LocalInfo;
+               public readonly int ParameterIndex;
+
+               readonly VariableInfo Parent;
+               VariableInfo[] sub_info;
+
+               protected VariableInfo (string name, Type type, int offset)
+               {
+                       this.Name = name;
+                       this.Offset = offset;
+                       this.TypeInfo = TypeInfo.GetTypeInfo (type);
+
+                       Length = TypeInfo.TotalLength;
+
+                       Initialize ();
+               }
+
+               protected VariableInfo (VariableInfo parent, TypeInfo type)
+               {
+                       this.Name = parent.Name;
+                       this.TypeInfo = type;
+                       this.Offset = parent.Offset + type.Offset;
+                       this.Parent = parent;
+                       this.Length = type.TotalLength;
+
+                       this.IsParameter = parent.IsParameter;
+                       this.LocalInfo = parent.LocalInfo;
+                       this.ParameterIndex = parent.ParameterIndex;
+
+                       Initialize ();
+               }
+
+               protected void Initialize ()
+               {
+                       TypeInfo[] sub_fields = TypeInfo.SubStructInfo;
+                       if (sub_fields != null) {
+                               sub_info = new VariableInfo [sub_fields.Length];
+                               for (int i = 0; i < sub_fields.Length; i++) {
+                                       if (sub_fields [i] != null)
+                                               sub_info [i] = new VariableInfo (this, sub_fields [i]);
+                               }
+                       } else
+                               sub_info = new VariableInfo [0];
+               }
+
+               public VariableInfo (LocalInfo local_info, int offset)
+                       : this (local_info.Name, local_info.VariableType, offset)
+               {
+                       this.LocalInfo = local_info;
+                       this.IsParameter = false;
+               }
+
+               public VariableInfo (string name, Type type, int param_idx, int offset)
+                       : this (name, type, offset)
+               {
+                       this.ParameterIndex = param_idx;
+                       this.IsParameter = true;
+               }
+
+               public bool IsAssigned (EmitContext ec)
+               {
+                       return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (this);
+               }
+
+               public bool IsAssigned (EmitContext ec, Location loc)
+               {
+                       if (IsAssigned (ec))
+                               return true;
+
+                       Report.Error (165, loc,
+                                     "Use of unassigned local variable `" + Name + "'");
+                       ec.CurrentBranching.SetAssigned (this);
+                       return false;
+               }
+
+               public bool IsAssigned (MyBitVector vector)
+               {
+                       if (vector [Offset])
+                               return true;
+
+                       for (VariableInfo parent = Parent; parent != null; parent = parent.Parent)
+                               if (vector [parent.Offset])
+                                       return true;
+
+                       // Return unless this is a struct.
+                       if (!TypeInfo.IsStruct)
+                               return false;
+
+                       // Ok, so each field must be assigned.
+                       for (int i = 0; i < TypeInfo.Length; i++) {
+                               if (!vector [Offset + i + 1])
+                                       return false;
+                       }
+
+                       // Ok, now check all fields which are structs.
+                       for (int i = 0; i < sub_info.Length; i++) {
+                               VariableInfo sinfo = sub_info [i];
+                               if (sinfo == null)
+                                       continue;
+
+                               if (!sinfo.IsAssigned (vector))
+                                       return false;
+                       }
+
+                       vector [Offset] = true;
+                       return true;
+               }
+
+               public void SetAssigned (EmitContext ec)
+               {
+                       if (ec.DoFlowAnalysis)
+                               ec.CurrentBranching.SetAssigned (this);
+               }
+
+               public void SetAssigned (MyBitVector vector)
+               {
+                       vector [Offset] = true;
+               }
+
+               public bool IsFieldAssigned (EmitContext ec, string name, Location loc)
+               {
+                       if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsFieldAssigned (this, name))
+                               return true;
+
+                       Report.Error (170, loc,
+                                     "Use of possibly unassigned field `" + name + "'");
+                       ec.CurrentBranching.SetFieldAssigned (this, name);
+                       return false;
+               }
+
+               public bool IsFieldAssigned (MyBitVector vector, string field_name)
+               {
+                       int field_idx = TypeInfo.GetFieldIndex (field_name);
+
+                       if (field_idx == 0)
+                               return true;
+
+                       return vector [Offset + field_idx];
+               }
+
+               public void SetFieldAssigned (EmitContext ec, string name)
+               {
+                       if (ec.DoFlowAnalysis)
+                               ec.CurrentBranching.SetFieldAssigned (this, name);
+               }
+
+               public void SetFieldAssigned (MyBitVector vector, string field_name)
+               {
+                       int field_idx = TypeInfo.GetFieldIndex (field_name);
+
+                       if (field_idx == 0)
+                               return;
+
+                       vector [Offset + field_idx] = true;
+               }
+
+               public VariableInfo GetSubStruct (string name)
+               {
+                       TypeInfo type = TypeInfo.GetSubStruct (name);
+
+                       if (type == null)
+                               return null;
+
+                       return new VariableInfo (this, type);
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("VariableInfo ({0}:{1}:{2}:{3}:{4})",
+                                             Name, TypeInfo, Offset, Length, IsParameter);
+               }
+       }
+
+       // <summary>
+       //   This is used by the flow code to hold the `layout' of the flow vector for
+       //   all locals and all parameters (ie. we create one instance of this class for the
+       //   locals and another one for the params).
+       // </summary>
+       public class VariableMap {
+               // <summary>
+               //   The number of variables in the map.
+               // </summary>
+               public readonly int Count;
+
+               // <summary>
+               //   Total length of the flow vector for this map.
+               // <summary>
+               public readonly int Length;
+
+               VariableInfo[] map;
+
+               public VariableMap (InternalParameters ip)
+               {
+                       Count = ip != null ? ip.Count : 0;
+                       
+                       // Dont bother allocating anything!
+                       if (Count == 0)
+                               return;
+                       
+                       Length = 0;
+
+                       for (int i = 0; i < Count; i++) {
+                               Parameter.Modifier mod = ip.ParameterModifier (i);
+
+                               if ((mod & Parameter.Modifier.OUT) == 0)
+                                       continue;
+
+                               // Dont allocate till we find an out var.
+                               if (map == null)
+                                       map = new VariableInfo [Count];
+
+                               map [i] = new VariableInfo (ip.ParameterName (i),
+                                       TypeManager.GetElementType (ip.ParameterType (i)), i, Length);
+
+                               Length += map [i].Length;
+                       }
+               }
+
+               public VariableMap (LocalInfo[] locals)
+                       : this (null, locals)
+               { }
+
+               public VariableMap (VariableMap parent, LocalInfo[] locals)
+               {
+                       int offset = 0, start = 0;
+                       if (parent != null && parent.map != null) {
+                               offset = parent.Length;
+                               start = parent.Count;
+                       }
+
+                       Count = locals.Length + start;
+                       
+                       if (Count == 0)
+                               return;
+                       
+                       map = new VariableInfo [Count];
+                       Length = offset;
+
+                       if (parent != null && parent.map != null) {
+                               parent.map.CopyTo (map, 0);
+                       }
+
+                       for (int i = start; i < Count; i++) {
+                               LocalInfo li = locals [i-start];
+
+                               if (li.VariableType == null)
+                                       continue;
+
+                               map [i] = li.VariableInfo = new VariableInfo (li, Length);
+                               Length += map [i].Length;
+                       }
+               }
+
+               // <summary>
+               //   Returns the VariableInfo for variable @index or null if we don't need to
+               //   compute assignment info for this variable.
+               // </summary>
+               public VariableInfo this [int index] {
+                       get {
+                               if (map == null)
+                                       return null;
+                               
+                               return map [index];
+                       }
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("VariableMap ({0}:{1})", Count, Length);
+               }
+       }
+
+       // <summary>
+       //   This is a special bit vector which can inherit from another bit vector doing a
+       //   copy-on-write strategy.  The inherited vector may have a smaller size than the
+       //   current one.
+       // </summary>
+       public class MyBitVector {
+               public readonly int Count;
+               public readonly MyBitVector InheritsFrom;
+
+               bool is_dirty;
+               BitArray vector;
+
+               public MyBitVector (int Count)
+                       : this (null, Count)
+               { }
+
+               public MyBitVector (MyBitVector InheritsFrom, int Count)
+               {
+                       this.InheritsFrom = InheritsFrom;
+                       this.Count = Count;
+               }
+
+               // <summary>
+               //   Checks whether this bit vector has been modified.  After setting this to true,
+               //   we won't use the inherited vector anymore, but our own copy of it.
+               // </summary>
+               public bool IsDirty {
+                       get {
+                               return is_dirty;
+                       }
+
+                       set {
+                               if (!is_dirty)
+                                       initialize_vector ();
+                       }
+               }
+
+               // <summary>
+               //   Get/set bit `index' in the bit vector.
+               // </summary>
+               public bool this [int index]
+               {
+                       get {
+                               if (index > Count)
+                                       throw new ArgumentOutOfRangeException ();
+
+                               // We're doing a "copy-on-write" strategy here; as long
+                               // as nobody writes to the array, we can use our parent's
+                               // copy instead of duplicating the vector.
+
+                               if (vector != null)
+                                       return vector [index];
+                               else if (InheritsFrom != null) {
+                                       BitArray inherited = InheritsFrom.Vector;
+
+                                       if (index < inherited.Count)
+                                               return inherited [index];
+                                       else
+                                               return false;
+                               } else
+                                       return false;
+                       }
+
+                       set {
+                               if (index > Count)
+                                       throw new ArgumentOutOfRangeException ();
+
+                               // Only copy the vector if we're actually modifying it.
+
+                               if (this [index] != value) {
+                                       initialize_vector ();
+
+                                       vector [index] = value;
+                               }
+                       }
+               }
+
+               // <summary>
+               //   If you explicitly convert the MyBitVector to a BitArray, you will get a deep
+               //   copy of the bit vector.
+               // </summary>
+               public static explicit operator BitArray (MyBitVector vector)
+               {
+                       vector.initialize_vector ();
+                       return vector.Vector;
+               }
+
+               // <summary>
+               //   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)
+               {
+                       BitArray new_array = new_vector.Vector;
+
+                       initialize_vector ();
+
+                       int upper;
+                       if (vector.Count < new_array.Count)
+                               upper = vector.Count;
+                       else
+                               upper = new_array.Count;
+
+                       for (int i = 0; i < upper; i++)
+                               vector [i] = vector [i] | new_array [i];
+               }
+
+               // <summary>
+               //   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)
+               {
+                       BitArray new_array = new_vector.Vector;
+
+                       initialize_vector ();
+
+                       int lower, upper;
+                       if (vector.Count < new_array.Count)
+                               lower = upper = vector.Count;
+                       else {
+                               lower = new_array.Count;
+                               upper = vector.Count;
+                       }
+
+                       for (int i = 0; i < lower; i++)
+                               vector [i] = vector [i] & new_array [i];
+
+                       for (int i = lower; i < upper; i++)
+                               vector [i] = false;
+               }
+
+               public static void And (ref MyBitVector target, MyBitVector vector)
+               {
+                       if (target != null)
+                               target.And (vector);
+                       else
+                               target = vector.Clone ();
+               }
+
+               public static void Or (ref MyBitVector target, MyBitVector vector)
+               {
+                       if (target != null)
+                               target.Or (vector);
+                       else
+                               target = vector.Clone ();
+               }
+
+               // <summary>
+               //   This does a deep copy of the bit vector.
+               // </summary>
+               public MyBitVector Clone ()
+               {
+                       MyBitVector retval = new MyBitVector (Count);
+
+                       retval.Vector = Vector;
+
+                       return retval;
+               }
+
+               BitArray Vector {
+                       get {
+                               if (vector != null)
+                                       return vector;
+                               else if (!is_dirty && (InheritsFrom != null))
+                                       return InheritsFrom.Vector;
+
+                               initialize_vector ();
+
+                               return vector;
+                       }
+
+                       set {
+                               initialize_vector ();
+
+                               for (int i = 0; i < System.Math.Min (vector.Count, value.Count); i++)
+                                       vector [i] = value [i];
+                       }
+               }
+
+               void initialize_vector ()
+               {
+                       if (vector != null)
+                               return;
+
+                       vector = new BitArray (Count, false);
+                       if (InheritsFrom != null)
+                               Vector = InheritsFrom.Vector;
+
+                       is_dirty = true;
+               }
+
+               public override string ToString ()
+               {
+                       StringBuilder sb = new StringBuilder ("{");
+
+                       BitArray vector = Vector;
+                       if (!IsDirty)
+                               sb.Append ("=");
+                       for (int i = 0; i < vector.Count; i++) {
+                               sb.Append (vector [i] ? "1" : "0");
+                       }
+                       
+                       sb.Append ("}");
+                       return sb.ToString ();
+               }
+       }
+}
diff --git a/mcs/bmcs/gen-il.cs b/mcs/bmcs/gen-il.cs
new file mode 100644 (file)
index 0000000..2dfeecc
--- /dev/null
@@ -0,0 +1,100 @@
+// gen-il.cs: Generates MSIL code from the CIR.Tree
+//
+// Author: Miguel de Icaza (miguel@ximian.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc. (http://www.ximian.com)
+//
+
+using System;
+using System.IO;
+using System.Collections;
+using CIR;
+
+namespace MSIL {
+
+       public class Generator : CIR.ITreeDump {
+               StreamWriter o;
+               int indent = 0;
+               
+               void output (string s)
+               {
+                       Console.Write (s);
+                       o.Write (s);
+               }
+
+               void space ()
+               {
+                       output (new String (' ', indent * 2));
+               }
+
+               void ioutput (string s)
+               {
+                       space ();
+                       output (s);
+               }
+
+               void ioutputl (string s)
+               {
+                       ioutput (s + "\n");
+               }
+
+               string ClassAttributes (Class c)
+               {
+                       // FIXME
+                       return "";
+               }
+
+               string ILName (string name)
+               {
+                       return name;
+               }
+
+               string ClassExtends (Class c)
+               {
+                       return "";
+               }
+               
+               void GenerateFromClass (Class c)
+               {
+                       ioutputl (".class " + ClassAttributes (c) + " " + ILName (c.Name));
+                       ioutputl (ClassExtends (c));
+                       ioutputl ("{");
+                       indent++;
+
+                       
+
+                       indent--;
+                       ioutputl ("}");
+               }
+               
+               void GenerateFromTypes (TypeContainer types)
+               {
+                       if (types.Types == null)
+                               return;
+                       
+                       foreach (DictionaryEntry de in types.Types){
+                               TypeContainer type = (TypeContainer) de.Value;
+                               
+                               if (type is Class)
+                                       GenerateFromClass ((Class) type);
+                       }
+                       
+               }
+               
+               public int GenerateFromTree (Tree tree, StreamWriter os)
+               {
+                       this.o = os;
+
+                       ioutputl (".assembly test.exe { }");
+                       GenerateFromTypes (tree.Types);
+                       return 0;
+               }
+
+               public void ParseOptions (string options)
+               {
+               }
+               
+       }
+}
diff --git a/mcs/bmcs/gen-treedump.cs b/mcs/bmcs/gen-treedump.cs
new file mode 100644 (file)
index 0000000..a4dbf32
--- /dev/null
@@ -0,0 +1,988 @@
+// cs-treedump.cs: Dumps the parsed tree to standard output
+//
+// Author: Miguel de Icaza (miguel@gnu.org)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc. (http://www.ximian.com)
+//
+// TODO:
+//     Variable declarations
+//      Fix precedence rules to lower the number of parenthesis.
+//
+
+using System;
+using System.IO;
+using System.Collections;
+using CIR;
+
+namespace Generator {
+       
+       public class TreeDump : CIR.ITreeDump {
+               StreamWriter o;
+               int indent;
+               bool indented;
+               bool tag_values;
+               
+               void space ()
+               {
+                       if (!indented)
+                               output (new String (' ', indent * 8));
+                       indented = true;
+               }
+
+               void output (string s)
+               {
+                       Console.Write (s);
+                       //o.Write (s);
+               }
+
+               void newline ()
+               {
+                       output ("\n");
+                       indented = false;
+               }
+
+               void output_newline (string s)
+               {
+                       output (s);
+                       newline ();
+               }
+               
+               void ioutput (string s)
+               {
+                       space ();
+                       output (s);
+               }
+
+               string GetParameter (Parameter par)
+               {
+                       Parameter.Modifier f = par.ModFlags;
+                       string mod = "";
+                       
+                       switch (f){
+                       case Parameter.Modifier.REF:
+                               mod = "ref "; break;
+                       case Parameter.Modifier.OUT:
+                               mod = "out "; break;
+                       case Parameter.Modifier.PARAMS:
+                               mod = "params "; break;
+                       case Parameter.Modifier.NONE:
+                               mod = ""; break;
+                       }
+                       return mod + par.Type + " " + par.Name;
+               }
+
+               string GetUnary (Unary u, int paren_level)
+               {
+                       string e;
+                       bool left = true;
+                       string s = "0_ERROR>";
+                       int prec = 0;
+                       
+                       switch (u.Oper){
+                       case Unary.Operator.UnaryPlus:
+                               prec = 10;
+                               s = "+";
+                               break;
+                               
+                       case Unary.Operator.UnaryNegation:
+                               prec = 10;
+                               s = "-";
+                               break;
+                               
+                       case Unary.Operator.LogicalNot:
+                               s = "!";
+                               prec = 10;
+                               break;
+                               
+                       case Unary.Operator.OnesComplement:
+                               prec = 10;
+                               s = "~";
+                               break;
+                               
+                       case Unary.Operator.Indirection:
+                               prec = 10;
+                               s = "*";
+                               break;
+                               
+                       case Unary.Operator.AddressOf:
+                               prec = 10;
+                               s = "&";
+                               break;
+                               
+                       case Unary.Operator.PreIncrement:
+                               prec = 11;
+                               s = "++";
+                               break;
+                               
+                       case Unary.Operator.PreDecrement:
+                               prec = 11;
+                               s = "--";
+                               break;
+                               
+                       case Unary.Operator.PostDecrement:
+                               left = false;
+                               prec = 12;
+                               s = "--";
+                               break;
+                               
+                       case Unary.Operator.PostIncrement:
+                               s = "++";
+                               prec = 12;
+                               left = false;
+                               break;
+                       }
+
+                       e = GetExpression (u.Expr, prec);
+                       if (left)
+                               e = s + e;
+                       else
+                               e = e + s;
+                       
+                       if (prec < paren_level)
+                               return "(" + e + ")";
+                       else
+                               return e;
+               }
+
+               string GetBinary (Binary b, int paren_level)
+               {
+                       string l, r;
+                       string op = null;
+                       bool assoc_left = true;
+                       int prec = 0;
+                       
+                       switch (b.Oper){
+                               case Binary.Operator.Multiply:
+                                       prec = 9;
+                                       op = "*"; break;
+
+                               case Binary.Operator.Division:
+                                       prec = 9;
+                                       op = "/"; break;
+                               
+                               case Binary.Operator.Modulus:
+                                       prec = 9;
+                                       op = "%"; break;
+                               
+                               case Binary.Operator.Addition:
+                                       prec = 8;
+                                       op = "+"; break;
+                               
+                               case Binary.Operator.Subtraction:
+                                       prec = 8;
+                                       op = "-"; break;
+                               
+                               case Binary.Operator.LeftShift:
+                                       prec = 7;
+                                       op = "<<"; break;
+                               
+                               case Binary.Operator.RightShift:
+                                       prec = 7;
+                                       op = ">>"; break;
+                               
+                               case Binary.Operator.LessThan:
+                                       prec = 6;
+                                       op = "<"; break;
+                               
+                               case Binary.Operator.GreaterThan:
+                                       prec = 6;
+                                       op = ">"; break;
+                               
+                               case Binary.Operator.LessThanOrEqual:
+                                       prec = 6;
+                                       op = "<="; break;
+                               
+                               case Binary.Operator.GreaterThanOrEqual:
+                                       prec = 6;
+                                       op = ">="; break;
+                               
+                               case Binary.Operator.Equality:
+                                       prec = 5;
+                                       op = "=="; break;
+                               
+                               case Binary.Operator.Inequality:
+                                       prec = 5;
+                                       op = "!="; break;
+                               
+                               case Binary.Operator.BitwiseAnd:
+                                       prec = 4;
+                                       op = "&"; break;
+                               
+                               case Binary.Operator.BitwiseOr:
+                                       prec = 2;
+                                       op = "|"; break;
+                               
+                               case Binary.Operator.LogicalAnd:
+                                       prec = 1;
+                                       op = "&&"; break;
+                               
+                               case Binary.Operator.LogicalOr:
+                                       prec = 0;
+                                       op = "||"; break;
+                               
+                               case Binary.Operator.ExclusiveOr:
+                                       prec = 3;
+                                       op = "^"; break;
+                       }
+
+                       l = GetExpression (b.Left, prec - (assoc_left ? 0 : 1));
+                       r = GetExpression (b.Right, prec - (assoc_left ? 0 : 1));
+                       
+                       if (prec <= paren_level)
+                               return "(" + l + " " + op + " " + r + ")";
+                       else
+                               return l + " " + op + " " + r;
+               }
+
+               string GetCast (Cast c)
+               {
+                       return "(" + c.TargetType + ") (" + GetExpression (c.Expr, 0) + ")";
+               }
+
+               string GetConditional (Conditional c)
+               {
+                       return "(" + GetExpression (c.Expr, 0) + ") ? (" +
+                               GetExpression (c.TrueExpr, 0) + ") : (" +
+                               GetExpression (c.FalseExpr, 0) + ")";
+               }
+
+               string GetAssign (Assign a)
+               {
+                       return GetExpression (a.Target, 0) + " = " + GetExpression (a.Source, 0);
+               }
+
+               string GetArguments (ArrayList args)
+               {
+                       string r = "";
+                       
+                       if (args != null){
+                               int top = args.Count;
+                               
+                               for (int i = 0; i < top; i++){
+                                       Argument arg = (Argument) args [i];
+                                               
+                                       switch (arg.ArgType){
+                                               case Argument.AType.Ref:
+                                                       r += "ref "; break;
+                                               case Argument.AType.Out:
+                                                       r += "out "; break;
+                                       }
+                                       r += GetExpression (arg.Expr, 0);
+
+                                       if (i+1 != top)
+                                               r += ", ";
+                               }
+                       }
+
+                       return "(" + r + ")";
+               }
+               
+               string GetInvocation (Invocation i)
+               {
+                       return GetExpression (i.Expr, 0) + " " + GetArguments (i.Arguments);
+               }
+
+               string GetNew (New n)
+               {
+                       return "new " + n.RequestedType + GetArguments (n.Arguments);
+               }
+
+               string GetTypeOf (TypeOf t)
+               {
+                       return "typeof (" + t.QueriedType + ")";
+               }
+
+               string GetSizeOf (SizeOf t)
+               {
+                       return "sizeof (" + t.QueriedType + ")";
+               }
+
+               string GetMemberAccess (MemberAccess m)
+               {
+                       return GetExpression (m.Expr, 0) +
+                               (tag_values ? "/* member access */ . " : ".") +
+                               m.Identifier;
+               }
+
+               string GetSimpleName (SimpleName n)
+               {
+                       string s = n.Name;
+                       
+                       if (s.StartsWith ("0_"))
+                               return "id_" + s;
+                       else
+                               return s;
+               }
+
+               string GetProbe (Probe p)
+               {
+                       string s = GetExpression (p.Expr, 6);
+
+                       if (p.Oper == CIR.Probe.Operator.Is)
+                               s += " is ";
+                       else if (p.Oper == CIR.Probe.Operator.As)
+                               s += " as ";
+                       else
+                               s += "UNHANDLED";
+
+                       s += p.ProbeType;
+
+                       return s;
+               }
+
+               string GetLocalVariableReference (LocalVariableReference l)
+               {
+                       if (tag_values)
+                               return "/* local var: */" + l.Name;
+                       else
+                               return l.Name;
+               }
+
+               string GetParameterReference (ParameterReference r)
+               {
+                       if (tag_values)
+                               return "/* par: */ " + r.Name;
+                       else
+                               return r.Name;
+               }
+               
+               string GetExpression (Expression e, int paren_level)
+               {
+                       if (e == null){
+                               return "<NULL EXPRESSION>";
+                       }
+                       
+                       if (e is Unary)
+                               return GetUnary ((Unary) e, paren_level);
+                       else if (e is Binary)
+                               return GetBinary ((Binary) e, paren_level);
+                       else if (e is Cast)
+                               return GetCast ((Cast) e);
+                       else if (e is Conditional)
+                               return GetConditional ((Conditional) e);
+                       else if (e is SimpleName)
+                               return GetSimpleName ((SimpleName)e);
+                       else if (e is LocalVariableReference)
+                               return GetLocalVariableReference ((LocalVariableReference) e);
+                       else if (e is ParameterReference)
+                               return GetParameterReference ((ParameterReference) e);
+                       else if (e is Assign)
+                               return GetAssign ((Assign) e);
+                       else if (e is Literal)
+                               return e.ToString ();
+                       else if (e is Invocation)
+                               return GetInvocation ((Invocation) e);
+                       else if (e is New)
+                               return GetNew ((New) e);
+                       else if (e is This)
+                               return "this";
+                       else if (e is TypeOf)
+                               return GetTypeOf ((TypeOf) e);
+                       else if (e is SizeOf)
+                               return GetSizeOf ((SizeOf) e);
+                       else if (e is MemberAccess)
+                               return GetMemberAccess ((MemberAccess) e);
+                       else if (e is Probe)
+                               return GetProbe ((Probe) e);
+                       else
+                               return "WARNING {" + e.ToString () + "} WARNING";
+               }
+               
+               void GenerateParameters (Parameters pars)
+               {
+                       Parameter [] pfixed;
+                       Parameter parray;
+
+                       pfixed = pars.FixedParameters;
+
+                       if (pfixed != null){
+                               for (int i = 0; i < pfixed.Length; i++){
+                                       output (GetParameter (pfixed [i]));
+                                       if (i+1 != pfixed.Length)
+                                               output (", ");
+                               }
+                       }
+
+                       parray = pars.ArrayParameter;
+                       if (parray != null){
+                               output (GetParameter (parray));
+                       }
+               }
+
+               void GenerateIf (If s)
+               {
+                       bool do_indent;
+                       
+                       output ("if (" + GetExpression (s.Expr, 0) + ") ");
+                       do_indent = !(s.TrueStatement is Block);
+                       if (do_indent)
+                               indent++;
+                       GenerateStatement (s.TrueStatement, true, false, false);
+                       if (do_indent)
+                               indent--;
+                       if (s.FalseStatement != null){
+                               ioutput ("else");
+                               newline ();
+                               GenerateStatement (s.FalseStatement, false, true, false);
+                       }
+               }
+
+               void GenerateDo (Do s)
+               {
+                       output ("do"); newline ();
+                       indent++;
+                       GenerateStatement (s.EmbeddedStatement, false, false, false);
+                       indent--;
+                       output (" while (" + GetExpression (s.Expr, 0) + ");");
+                       newline ();
+               }
+
+               void GenerateWhile (While s)
+               {
+                       output ("while (" + GetExpression (s.Expr, 0) + ")");
+                       GenerateStatement (s.Statement, true, true, false);
+               }
+
+               void GenerateFor (For s)
+               {
+                       output ("for (");
+                       if (! (s.InitStatement == EmptyStatement.Value))
+                               GenerateStatement (s.InitStatement, true, true, true);
+                       output ("; ");
+                       output (GetExpression (s.Test, 0));
+                       output ("; ");
+                       if (! (s.Increment == EmptyStatement.Value))
+                               GenerateStatement (s.Increment, true, true, true);
+                       output (") ");
+                       GenerateStatement (s.Statement, true, true, false);
+               }
+
+               void GenerateReturn (Return s)
+               {
+                       output ("return " +
+                               (s.Expr != null ?
+                                GetExpression (s.Expr, 0) : "" + ";") +
+                               ";");
+                       newline ();
+               }
+
+               void GenerateGoto (Goto s)
+               {
+                       output ("goto " + s.Target + ";");
+                       newline ();
+               }
+
+               void GenerateThrow (Throw s)
+               {
+               }
+
+               void GenerateStatementExpression (StatementExpression s)
+               {
+                       output (GetExpression (s.Expr, 0) + ";");
+                       newline ();
+               }
+
+               void GenerateSwitchLabels (ArrayList labels)
+               {
+                       foreach (SwitchLabel sl in labels){
+                               Expression lab = sl.Label;
+                               
+                               if (lab == null){
+                                       ioutput ("default:");
+                                       newline ();
+                               } else {
+                                       ioutput ("case " + GetExpression (lab, 0) + ":");
+                                       newline ();
+                               }
+                       }
+               }
+               
+               void GenerateSwitch (Switch s)
+               {
+                       output_newline ("switch (" + GetExpression (s.Expr, 0) + ")");
+                       foreach (SwitchSection ss in s.Sections){
+                               GenerateSwitchLabels (ss.Labels);
+                               GenerateBlock (ss.Block, false, false);
+                       }
+               }
+               
+               void GenerateChecked (Checked c)
+               {
+                       output ("checked ");
+                       GenerateBlock (c.Block, false, false);
+               }
+
+               void GenerateUnchecked (Unchecked c)
+               {
+                       output ("unchecked ");
+                       GenerateBlock (c.Block, false, false);
+               }
+
+               void GenerateCatchClauses (ArrayList list)
+               {
+                       foreach (Catch c in list){
+                               space ();
+                               output ("catch ");
+                               
+                               if (c.Type != null){
+                                       output ("(" + c.Type +
+                                               (c.Name != null ? " " + c.Name : "") + ")");
+                               } 
+                               GenerateBlock (c.Block, false, false);
+                       }
+               }
+
+               void GenerateTry (Try t)
+               {
+                       output ("try");
+                       GenerateBlock (t.Block, false, false);
+
+                       if (t.Specific != null){
+                               GenerateCatchClauses (t.Specific);
+                       }
+
+                       if (t.General != null){
+                               space ();
+                               output ("catch");
+                               GenerateBlock (t.Block, false, false);
+                       }
+
+                       if (t.Fini != null){
+                               GenerateBlock (t.Fini, false, false);
+                       }
+               }
+               
+               void GenerateStatement (Statement s, bool doPlacement, bool blockFlushesLine, bool embedded)
+               {
+                       if (s == null){
+                               output ("WARNING: got a null Statement");
+                               newline ();
+                               return;
+                       }
+
+                       if (doPlacement){
+                               if (s is Block){
+                                       GenerateBlock ((Block) s, doPlacement, embedded);
+                                       return;
+                               } else 
+                                       newline ();
+                       } 
+                               
+                       space ();
+                       if (s is If)
+                               GenerateIf ((If) s);
+                       else if (s is Do)
+                               GenerateDo ((Do) s);
+                       else if (s is While)
+                               GenerateWhile ((While) s);
+                       else if (s is For)
+                               GenerateFor ((For) s);
+                       else if (s is Return)
+                               GenerateReturn ((Return) s);
+                       else if (s is Goto)
+                               GenerateGoto ((Goto) s);
+                       else if (s is Throw)
+                               GenerateThrow ((Throw) s);
+                       else if (s is Break)
+                               output_newline ("break;");
+                       else if (s is Continue)
+                               output_newline ("continue;");
+                       else if (s == EmptyStatement.Value)
+                               output_newline ("/* empty statement */;");
+                       else if (s is Block)
+                               GenerateBlock ((Block) s, doPlacement, embedded);
+                       else if (s is StatementExpression)
+                               GenerateStatementExpression ((StatementExpression) s);
+                       else if (s is Switch)
+                               GenerateSwitch ((Switch) s);
+                       else if (s is Checked)
+                               GenerateChecked ((Checked) s);
+                       else if (s is Unchecked)
+                               GenerateUnchecked ((Unchecked) s);
+                       else if (s is Try)
+                               GenerateTry ((Try) s);
+                       else {
+                               System.Type t = s.GetType ();
+
+                               output ("\n*****UNKNOWN Statement:" + t.ToString ());
+                       }
+               }
+
+               //
+               // embedded is used only for things like the For thing
+               // that has blocks but for display purposes we want to keep
+               // without newlines.
+               void GenerateBlock (Block b, bool doPlacement, bool embedded)
+               {
+                       if (b.Label != null)
+                               output (b.Label + ":");
+
+                       if (!b.Implicit){
+                               if (!doPlacement)
+                                       space ();
+                       
+                               output ("{");
+                               if (!embedded)
+                                       newline ();
+                               indent++;
+                       }
+
+                       if (b.Variables != null){
+                               foreach (DictionaryEntry entry in b.Variables){
+                                       VariableInfo vi = (VariableInfo) entry.Value;
+                                       
+                                       space ();
+                                       output_newline (
+                                               vi.Type + " " +
+                                               (string) entry.Key + ";");
+                               }
+                               newline ();
+                       }
+                       
+                       foreach (Statement s in b.Statements){
+                               GenerateStatement (s, false, true, false);
+                       }
+                       
+                       if (!b.Implicit){
+                               indent--;
+                               ioutput ("}");
+                               if (!embedded)
+                                       newline ();
+                       }
+               }
+               
+               void GenerateMethod (Method m)
+               {
+                       ioutput (GetModifiers (m.ModFlags) +
+                                m.ReturnType + " " +
+                                m.Name + " (");
+                       GenerateParameters (m.Parameters);
+                       output_newline (")");
+                       
+
+                       GenerateBlock (m.Block, false, false);
+                       newline ();
+               }
+
+               void GenerateInterfaceMethod (InterfaceMethod imethod)
+               {
+                       space ();
+                       output (imethod.IsNew ? "new " : "");
+                       output (imethod.ReturnType + " " + imethod.Name + " (");
+                       GenerateParameters (imethod.Parameters);
+                       output (");");
+                       newline ();
+               }
+
+               void GenerateInterfaceProperty (InterfaceProperty iprop)
+               {
+                       space ();
+                       output (iprop.IsNew ? "new " : "");
+                       output (iprop.Type + " " + iprop.Name + " { ");
+                       if (iprop.HasGet) output ("get; ");
+                       if (iprop.HasSet) output ("set; ");
+                       output ("}");
+                       newline ();
+               }
+               
+               void GenerateInterfaceEvent (InterfaceEvent ievent)
+               {
+                       space ();
+                       output ((ievent.IsNew ? "new " : "") + "event ");
+                       output (ievent.Type + " " + ievent.Name + ";");
+                       newline ();
+               }
+               
+               void GenerateInterfaceIndexer (InterfaceIndexer iindexer)
+               {
+                       space ();
+                       output (iindexer.IsNew ? "new " : "");
+                       output (iindexer.Type + " this [");
+                       output (iindexer.Parameters + "] {");
+                       if (iindexer.HasGet) output ("get; ");
+                       if (iindexer.HasSet) output ("set; ");
+                       output ("}");
+                       newline ();
+               }
+
+               string GenIfaceBases (Interface iface)
+               {
+                       return GenBases (iface.Bases);
+               }
+               
+               void GenerateInterface (Interface iface)
+               {
+                       ioutput (GetModifiers (iface.ModFlags) + "interface " +
+                                ClassName (iface.Name) + GenIfaceBases (iface) + " {");
+                       newline ();
+                       indent++;
+                       
+                       if (iface.InterfaceMethods != null){
+                               foreach (DictionaryEntry de in iface.InterfaceMethods){
+                                       InterfaceMethod method = (InterfaceMethod) de.Value;
+                                       GenerateInterfaceMethod (method);
+                               }
+                       }
+
+                       if (iface.InterfaceProperties != null){
+                               foreach (DictionaryEntry de in iface.InterfaceProperties){
+                                       InterfaceProperty iprop = (InterfaceProperty) de.Value;
+                                       GenerateInterfaceProperty (iprop);
+                               }
+                       }
+
+                       if (iface.InterfaceEvents != null){
+                               foreach (DictionaryEntry de in iface.InterfaceEvents){
+                                       InterfaceEvent ievent = (InterfaceEvent) de.Value;
+                                       GenerateInterfaceEvent (ievent);
+                               }
+                       }
+
+                       if (iface.InterfaceIndexers != null){
+                               foreach (DictionaryEntry de in iface.InterfaceIndexers){
+                                       InterfaceIndexer iindexer = (InterfaceIndexer) de.Value;
+                                       GenerateInterfaceIndexer (iindexer);
+                               }
+                       }
+                       indent--;
+                       ioutput ("}");
+                       newline ();
+                       newline ();
+               }
+
+               void GenerateField (Field f)
+               {
+                       space ();
+                       output (GetModifiers (f.ModFlags) + 
+                               f.Type + " " + f.Name);
+                       if (f.Initializer != null){
+                               if (f.Initializer is Expression)
+                                       output (" = " + GetExpression ((Expression) f.Initializer, 0));
+                               else
+                                       output ("ADD SUPPORT FOR ARRAYS");
+                       }
+                       output (";");
+                       newline ();
+               }
+
+               void GenerateConstructor (Constructor c)
+               {
+                       ConstructorInitializer init = c.Initializer;
+
+                       space ();
+                       output (GetModifiers (c.ModFlags) + c.Name + " (");
+                       GenerateParameters (c.Parameters);
+                       output (")");
+
+                       if (init != null){
+                               if (init is ConstructorThisInitializer)
+                                       output (": this (");
+                               else
+                                       output (": base (");
+                               output (GetArguments (init.Arguments));
+                               output (")");
+                       }
+                       newline ();
+                       GenerateBlock (c.Block, false, false);
+               }
+
+               void GenerateProperty (Property prop)
+               {
+                       space ();
+                       output (GetModifiers (prop.ModFlags) + prop.Type +
+                               " " + prop.Name + " {");
+                       newline ();
+                       indent++;
+                       if (prop.Get != null){
+                               space ();
+                               output ("get ");
+                               GenerateBlock (prop.Get, false, false);
+                               newline (); 
+                       }
+
+                       if (prop.Set != null){
+                               space ();
+                               output ("set ");
+                               GenerateBlock (prop.Set, false, false);
+                       }
+                       indent--;
+                       space ();
+                       output ("}");
+                       newline ();
+               }
+
+               void GenerateEnum (CIR.Enum e)
+               {
+                       space ();
+                       output ("enum " + e.Name + " {");
+                       newline ();
+
+                       indent++;
+                       foreach (string name in e.ValueNames){
+                               Expression expr = e [name];
+
+                               space ();
+
+                               output (name);
+                               if (expr != null)
+                                       output (" = " + GetExpression (expr, 0));
+
+                               output (",");
+                               newline ();
+                       }
+                       indent--;
+                       space ();
+                       output_newline ("}");
+               }
+               
+               void GenerateTypeContainerData (TypeContainer tc)
+               {
+                       if (tc.Constants != null){
+                               foreach (Constant c in tc.Constants){
+                                       space ();
+
+                                       output ("const " + c.ConstantType + " " + c.Name + " = " +
+                                               GetExpression (c.Expr, 0) + ";");
+                                       newline ();
+                               }
+                               newline ();
+                       }
+
+                       if (tc.Enums != null){
+                               foreach (CIR.Enum e in tc.Enums)
+                                       GenerateEnum (e);
+                       }
+
+                       if (tc.Fields != null){
+                               foreach (Field f in tc.Fields)
+                                       GenerateField (f);
+                               newline ();
+                       }
+
+                       if (tc.Constructors != null){
+                               foreach (Constructor c in tc.Constructors)
+                                       GenerateConstructor (c);
+
+                               newline ();
+                                       
+                       }
+
+                       if (tc.Properties != null){
+                               foreach (Property prop in tc.Properties)
+                                       GenerateProperty (prop);
+                       }
+                       
+                       GenerateFromTypes (tc);
+                       
+                       if (tc.Methods != null){
+                               foreach (Method m in tc.Methods){
+                                       GenerateMethod (m);
+                               }
+                       }
+               }
+
+               string GetModifiers (int mod_flags)
+               {
+                       string s = "";
+
+                       for (int i = 1; i <= (int) CIR.Modifiers.TOP; i <<= 1){
+                               if ((mod_flags & i) != 0)
+                                       s += Modifiers.Name (i) + " ";
+                       }
+
+                       return s;
+               }
+
+               string ClassName (string name)
+               {
+                       return name;
+                       //return name.Substring (1 + name.LastIndexOf ('.'));
+               }
+
+               string GenBases (ArrayList bases)
+               {
+                       if (bases == null)
+                               return "";
+
+                       string res = ": ";
+                       int top = bases.Count;
+                       for (int i = 0; i < bases.Count; i++){
+                               Type t = (Type) bases [i];
+
+                               res += t.Name;
+                               if (i + 1 != top)
+                                       res += ", ";
+                       }
+                       return res;
+               }
+               
+               string GenClassBases (Class c)
+               {
+                       return GenBases (c.Bases);
+               }
+               
+               void GenerateFromClass (Class c)
+               {
+                       ioutput (GetModifiers (c.ModFlags) + "class " + ClassName (c.Name) +
+                                " " + GenClassBases (c) + " {");
+                       newline ();
+                       indent++;
+                       
+                       GenerateTypeContainerData (c);
+
+                       indent--;
+                       ioutput ("}");
+                       newline ();
+                       newline ();
+               }
+
+               void GenerateFromStruct (Struct s)
+               {
+                       GenerateTypeContainerData (s);
+               }
+               
+               void GenerateFromTypes (TypeContainer types)
+               {
+                       if (types.Types == null)
+                               return;
+                       
+                       foreach (DictionaryEntry de in types.Types){
+                               TypeContainer type = (TypeContainer) de.Value;
+                               
+                               if (type is Class)
+                                       GenerateFromClass ((Class) type);
+                               if (type is Struct)
+                                       GenerateFromStruct ((Struct) type);
+                                       
+                       }
+
+                       if (types.Interfaces != null){
+                               foreach (DictionaryEntry de in types.Interfaces){
+                                       Interface iface = (Interface) de.Value;
+
+                                       GenerateInterface (iface);
+                               }
+                       }
+               }
+               
+               public int Dump (Tree tree, StreamWriter output)
+               {
+                       this.o = output;
+
+                       indent = 0;
+                       GenerateFromTypes (tree.Types);
+
+                       return 0;
+               }
+
+               public void ParseOptions (string options)
+               {
+                       if (options == "tag")
+                               tag_values = true;
+               }
+       }
+}
+
+
diff --git a/mcs/bmcs/generic.cs b/mcs/bmcs/generic.cs
new file mode 100644 (file)
index 0000000..938a1c3
--- /dev/null
@@ -0,0 +1,2129 @@
+//
+// generic.cs: Generics support
+//
+// Authors: Martin Baulig (martin@ximian.com)
+//          Miguel de Icaza (miguel@ximian.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
+//
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Globalization;
+using System.Collections;
+using System.Text;
+using System.Text.RegularExpressions;
+       
+namespace Mono.CSharp {
+
+       public abstract class GenericConstraints {
+               public abstract GenericParameterAttributes Attributes {
+                       get;
+               }
+
+               public bool HasConstructorConstraint {
+                       get { return (Attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0; }
+               }
+
+               public bool HasReferenceTypeConstraint {
+                       get { return (Attributes & GenericParameterAttributes.ReferenceTypeConstraint) != 0; }
+               }
+
+               public bool HasValueTypeConstraint {
+                       get { return (Attributes & GenericParameterAttributes.ValueTypeConstraint) != 0; }
+               }
+
+               public virtual bool HasClassConstraint {
+                       get { return ClassConstraint != null; }
+               }
+
+               public abstract Type ClassConstraint {
+                       get;
+               }
+
+               public abstract Type[] InterfaceConstraints {
+                       get;
+               }
+
+               public abstract Type EffectiveBaseClass {
+                       get;
+               }
+
+               // <summary>
+               //   Returns whether the type parameter is "known to be a reference type".
+               // </summary>
+               public virtual bool IsReferenceType {
+                       get {
+                               if (HasReferenceTypeConstraint)
+                                       return true;
+                               if (HasValueTypeConstraint)
+                                       return false;
+
+                               if (ClassConstraint != null) {
+                                       if (ClassConstraint.IsValueType)
+                                               return false;
+
+                                       if (ClassConstraint != TypeManager.object_type)
+                                               return true;
+                               }
+
+                               foreach (Type t in InterfaceConstraints) {
+                                       if (!t.IsGenericParameter)
+                                               continue;
+
+                                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (t);
+                                       if ((gc != null) && gc.IsReferenceType)
+                                               return true;
+                               }
+
+                               return false;
+                       }
+               }
+
+               // <summary>
+               //   Returns whether the type parameter is "known to be a value type".
+               // </summary>
+               public virtual bool IsValueType {
+                       get {
+                               if (HasValueTypeConstraint)
+                                       return true;
+                               if (HasReferenceTypeConstraint)
+                                       return false;
+
+                               if (ClassConstraint != null) {
+                                       if (!ClassConstraint.IsValueType)
+                                               return false;
+
+                                       if (ClassConstraint != TypeManager.value_type)
+                                               return true;
+                               }
+
+                               foreach (Type t in InterfaceConstraints) {
+                                       if (!t.IsGenericParameter)
+                                               continue;
+
+                                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (t);
+                                       if ((gc != null) && gc.IsValueType)
+                                               return true;
+                               }
+
+                               return false;
+                       }
+               }
+       }
+
+       public enum SpecialConstraint
+       {
+               Constructor,
+               ReferenceType,
+               ValueType
+       }
+
+       //
+       // Tracks the constraints for a type parameter
+       //
+       public class Constraints : GenericConstraints {
+               string name;
+               ArrayList constraints;
+               Location loc;
+               
+               //
+               // name is the identifier, constraints is an arraylist of
+               // Expressions (with types) or `true' for the constructor constraint.
+               // 
+               public Constraints (string name, ArrayList constraints,
+                                   Location loc)
+               {
+                       this.name = name;
+                       this.constraints = constraints;
+                       this.loc = loc;
+               }
+
+               public string TypeParameter {
+                       get {
+                               return name;
+                       }
+               }
+
+               GenericParameterAttributes attrs;
+               TypeExpr class_constraint;
+               ArrayList iface_constraints;
+               ArrayList type_param_constraints;
+               int num_constraints, first_constraint;
+               Type class_constraint_type;
+               Type[] iface_constraint_types;
+               Type effective_base_type;
+
+               public bool Resolve (EmitContext ec)
+               {
+                       DeclSpace ds = ec.DeclSpace;
+
+                       iface_constraints = new ArrayList ();
+                       type_param_constraints = new ArrayList ();
+
+                       foreach (object obj in constraints) {
+                               if (HasConstructorConstraint) {
+                                       Report.Error (401, loc,
+                                                     "The new() constraint must be last.");
+                                       return false;
+                               }
+
+                               if (obj is SpecialConstraint) {
+                                       SpecialConstraint sc = (SpecialConstraint) obj;
+
+                                       if (sc == SpecialConstraint.Constructor) {
+                                               if (!HasValueTypeConstraint) {
+                                                       attrs |= GenericParameterAttributes.DefaultConstructorConstraint;
+                                                       continue;
+                                               }
+
+                                               Report.Error (
+                                                       451, loc, "The new () constraint " +
+                                                       "cannot be used with the `struct' " +
+                                                       "constraint.");
+                                               return false;
+                                       }
+
+                                       if ((num_constraints > 0) || HasReferenceTypeConstraint || HasValueTypeConstraint) {
+                                               Report.Error (449, loc,
+                                                             "The `class' or `struct' " +
+                                                             "constraint must be first");
+                                               return false;
+                                       }
+
+                                       if (sc == SpecialConstraint.ReferenceType)
+                                               attrs |= GenericParameterAttributes.ReferenceTypeConstraint;
+                                       else
+                                               attrs |= GenericParameterAttributes.ValueTypeConstraint;
+                                       continue;
+                               }
+
+                               TypeExpr expr;
+                               if (obj is ConstructedType) {
+                                       ConstructedType cexpr = (ConstructedType) obj;
+                                       if (!cexpr.ResolveConstructedType (ec))
+                                               return false;
+                                       expr = cexpr;
+                               } else
+                                       expr = ((Expression) obj).ResolveAsTypeTerminal (ec);
+
+                               if (expr == null)
+                                       return false;
+
+                               TypeParameterExpr texpr = expr as TypeParameterExpr;
+                               if (texpr != null)
+                                       type_param_constraints.Add (expr);
+                               else if (expr.IsInterface)
+                                       iface_constraints.Add (expr);
+                               else if (class_constraint != null) {
+                                       Report.Error (406, loc,
+                                                     "`{0}': the class constraint for `{1}' " +
+                                                     "must come before any other constraints.",
+                                                     expr.Name, name);
+                                       return false;
+                               } else if (HasReferenceTypeConstraint || HasValueTypeConstraint) {
+                                       Report.Error (450, loc, "`{0}': cannot specify both " +
+                                                     "a constraint class and the `class' " +
+                                                     "or `struct' constraint.", expr.Name);
+                                       return false;
+                               } else
+                                       class_constraint = expr;
+
+                               num_constraints++;
+                       }
+
+                       return true;
+               }
+
+               bool CheckTypeParameterConstraints (TypeParameter tparam, Hashtable seen)
+               {
+                       seen.Add (tparam, true);
+
+                       Constraints constraints = tparam.Constraints;
+                       if (constraints == null)
+                               return true;
+
+                       if (constraints.HasValueTypeConstraint) {
+                               Report.Error (456, loc, "Type parameter `{0}' has " +
+                                             "the `struct' constraint, so it cannot " +
+                                             "be used as a constraint for `{1}'",
+                                             tparam.Name, name);
+                               return false;
+                       }
+
+                       if (constraints.type_param_constraints == null)
+                               return true;
+
+                       foreach (TypeParameterExpr expr in constraints.type_param_constraints) {
+                               if (seen.Contains (expr.TypeParameter)) {
+                                       Report.Error (454, loc, "Circular constraint " +
+                                                     "dependency involving `{0}' and `{1}'",
+                                                     tparam.Name, expr.Name);
+                                       return false;
+                               }
+
+                               if (!CheckTypeParameterConstraints (expr.TypeParameter, seen))
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               public bool ResolveTypes (EmitContext ec)
+               {
+                       foreach (object obj in constraints) {
+                               ConstructedType cexpr = obj as ConstructedType;
+                               if (cexpr == null)
+                                       continue;
+
+                               if (!cexpr.CheckConstraints (ec))
+                                       return false;
+                       }
+
+                       foreach (TypeParameterExpr expr in type_param_constraints) {
+                               Hashtable seen = new Hashtable ();
+                               if (!CheckTypeParameterConstraints (expr.TypeParameter, seen))
+                                       return false;
+                       }
+
+                       ArrayList list = new ArrayList ();
+
+                       foreach (TypeExpr iface_constraint in iface_constraints) {
+                               foreach (Type type in list) {
+                                       if (!type.Equals (iface_constraint.Type))
+                                               continue;
+
+                                       Report.Error (405, loc,
+                                                     "Duplicate constraint `{0}' for type " +
+                                                     "parameter `{1}'.", iface_constraint.Type,
+                                                     name);
+                                       return false;
+                               }
+
+                               list.Add (iface_constraint.Type);
+                       }
+
+                       foreach (TypeParameterExpr expr in type_param_constraints) {
+                               foreach (Type type in list) {
+                                       if (!type.Equals (expr.Type))
+                                               continue;
+
+                                       Report.Error (405, loc,
+                                                     "Duplicate constraint `{0}' for type " +
+                                                     "parameter `{1}'.", expr.Type, name);
+                                       return false;
+                               }
+
+                               list.Add (expr.Type);
+                       }
+
+                       iface_constraint_types = new Type [list.Count];
+                       list.CopyTo (iface_constraint_types, 0);
+
+                       if (class_constraint != null) {
+                               class_constraint_type = class_constraint.Type;
+                               if (class_constraint_type == null)
+                                       return false;
+
+                               if (class_constraint_type.IsSealed) {
+                                       Report.Error (701, loc,
+                                                     "`{0}' is not a valid bound.  Bounds " +
+                                                     "must be interfaces or non sealed " +
+                                                     "classes", class_constraint_type);
+                                       return false;
+                               }
+
+                               if ((class_constraint_type == TypeManager.array_type) ||
+                                   (class_constraint_type == TypeManager.delegate_type) ||
+                                   (class_constraint_type == TypeManager.enum_type) ||
+                                   (class_constraint_type == TypeManager.value_type) ||
+                                   (class_constraint_type == TypeManager.object_type)) {
+                                       Report.Error (702, loc,
+                                                     "Bound cannot be special class `{0}'",
+                                                     class_constraint_type);
+                                       return false;
+                               }
+                       }
+
+                       if (class_constraint_type != null)
+                               effective_base_type = class_constraint_type;
+                       else if (HasValueTypeConstraint)
+                               effective_base_type = TypeManager.value_type;
+                       else
+                               effective_base_type = TypeManager.object_type;
+
+                       return true;
+               }
+
+               public bool CheckDependencies (EmitContext ec)
+               {
+                       foreach (TypeParameterExpr expr in type_param_constraints) {
+                               if (!CheckDependencies (expr.TypeParameter, ec))
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               bool CheckDependencies (TypeParameter tparam, EmitContext ec)
+               {
+                       Constraints constraints = tparam.Constraints;
+                       if (constraints == null)
+                               return true;
+
+                       if (HasValueTypeConstraint && constraints.HasClassConstraint) {
+                               Report.Error (455, loc, "Type parameter `{0}' inherits " +
+                                             "conflicting constraints `{1}' and `{2}'",
+                                             name, constraints.ClassConstraint,
+                                             "System.ValueType");
+                               return false;
+                       }
+
+                       if (HasClassConstraint && constraints.HasClassConstraint) {
+                               Type t1 = ClassConstraint;
+                               TypeExpr e1 = class_constraint;
+                               Type t2 = constraints.ClassConstraint;
+                               TypeExpr e2 = constraints.class_constraint;
+
+                               if (!Convert.ImplicitReferenceConversionExists (ec, e1, t2) &&
+                                   !Convert.ImplicitReferenceConversionExists (ec, e2, t1)) {
+                                       Report.Error (455, loc,
+                                                     "Type parameter `{0}' inherits " +
+                                                     "conflicting constraints `{1}' and `{2}'",
+                                                     name, t1, t2);
+                                       return false;
+                               }
+                       }
+
+                       if (constraints.type_param_constraints == null)
+                               return true;
+
+                       foreach (TypeParameterExpr expr in constraints.type_param_constraints) {
+                               if (!CheckDependencies (expr.TypeParameter, ec))
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               public void Define (GenericTypeParameterBuilder type)
+               {
+                       type.SetGenericParameterAttributes (attrs);
+               }
+
+               public override GenericParameterAttributes Attributes {
+                       get { return attrs; }
+               }
+
+               public override bool HasClassConstraint {
+                       get { return class_constraint != null; }
+               }
+
+               public override Type ClassConstraint {
+                       get { return class_constraint_type; }
+               }
+
+               public override Type[] InterfaceConstraints {
+                       get { return iface_constraint_types; }
+               }
+
+               public override Type EffectiveBaseClass {
+                       get { return effective_base_type; }
+               }
+
+               internal bool IsSubclassOf (Type t)
+               {
+                       if ((class_constraint_type != null) &&
+                           class_constraint_type.IsSubclassOf (t))
+                               return true;
+
+                       if (iface_constraint_types == null)
+                               return false;
+
+                       foreach (Type iface in iface_constraint_types) {
+                               if (TypeManager.IsSubclassOf (iface, t))
+                                       return true;
+                       }
+
+                       return false;
+               }
+
+               public bool CheckInterfaceMethod (EmitContext ec, GenericConstraints gc)
+               {
+                       if (!ResolveTypes (ec))
+                               return false;
+
+                       if (gc.Attributes != attrs)
+                               return false;
+
+                       if (HasClassConstraint != gc.HasClassConstraint)
+                               return false;
+                       if (HasClassConstraint && !TypeManager.IsEqual (gc.ClassConstraint, ClassConstraint))
+                               return false;
+
+                       int gc_icount = gc.InterfaceConstraints != null ?
+                               gc.InterfaceConstraints.Length : 0;
+                       int icount = InterfaceConstraints != null ?
+                               InterfaceConstraints.Length : 0;
+
+                       if (gc_icount != icount)
+                               return false;
+
+                       foreach (Type iface in gc.InterfaceConstraints) {
+                               bool ok = false;
+                               foreach (Type check in InterfaceConstraints) {
+                                       if (TypeManager.IsEqual (iface, check)) {
+                                               ok = true;
+                                               break;
+                                       }
+                               }
+
+                               if (!ok)
+                                       return false;
+                       }
+
+                       return true;
+               }
+       }
+
+       //
+       // This type represents a generic type parameter
+       //
+       public class TypeParameter : MemberCore, IMemberContainer {
+               string name;
+               GenericConstraints gc;
+               Constraints constraints;
+               Location loc;
+               GenericTypeParameterBuilder type;
+
+               public TypeParameter (TypeContainer parent, string name,
+                                     Constraints constraints, Location loc)
+                       : base (parent, new MemberName (name), null, loc)
+               {
+                       this.name = name;
+                       this.constraints = constraints;
+                       this.loc = loc;
+               }
+
+               public GenericConstraints GenericConstraints {
+                       get {
+                               return gc != null ? gc : constraints;
+                       }
+               }
+
+               public Constraints Constraints {
+                       get {
+                               return constraints;
+                       }
+               }
+
+               public bool HasConstructorConstraint {
+                       get {
+                               if (constraints != null)
+                                       return constraints.HasConstructorConstraint;
+
+                               return false;
+                       }
+               }
+
+               public Type Type {
+                       get {
+                               return type;
+                       }
+               }
+
+               public bool Resolve (DeclSpace ds)
+               {
+                       if (constraints != null)
+                               return constraints.Resolve (ds.EmitContext);
+
+                       return true;
+               }
+
+               public void Define (GenericTypeParameterBuilder type)
+               {
+                       if (this.type != null)
+                               throw new InvalidOperationException ();
+
+                       this.type = type;
+                       TypeManager.AddTypeParameter (type, this);
+               }
+
+               public void DefineConstraints ()
+               {
+                       if (constraints != null)
+                               constraints.Define (type);
+               }
+
+               public bool DefineType (EmitContext ec)
+               {
+                       return DefineType (ec, null, null, false);
+               }
+
+               public bool DefineType (EmitContext ec, MethodBuilder builder,
+                                       MethodInfo implementing, bool is_override)
+               {
+                       if (implementing != null) {
+                               if (is_override && (constraints != null)) {
+                                       Report.Error (
+                                               460, loc, "Constraints for override and " +
+                                               "explicit interface implementation methods " +
+                                               "are inherited from the base method so they " +
+                                               "cannot be specified directly");
+                                       return false;
+                               }
+
+                               MethodBase mb = implementing;
+                               if (mb.Mono_IsInflatedMethod)
+                                       mb = mb.GetGenericMethodDefinition ();
+
+                               int pos = type.GenericParameterPosition;
+                               ParameterData pd = Invocation.GetParameterData (mb);
+                               GenericConstraints temp_gc = pd.GenericConstraints (pos);
+                               Type mparam = mb.GetGenericArguments () [pos];
+
+                               if (temp_gc != null)
+                                       gc = new InflatedConstraints (temp_gc, implementing.DeclaringType);
+                               else if (constraints != null)
+                                       gc = new InflatedConstraints (constraints, implementing.DeclaringType);
+
+                               bool ok = true;
+                               if (constraints != null) {
+                                       if (temp_gc == null)
+                                               ok = false;
+                                       else if (!constraints.CheckInterfaceMethod (ec, gc))
+                                               ok = false;
+                               } else {
+                                       if (!is_override && (temp_gc != null))
+                                               ok = false;
+                               }
+
+                               if (!ok) {
+                                       Report.SymbolRelatedToPreviousError (implementing);
+
+                                       Report.Error (
+                                               425, loc, "The constraints for type " +
+                                               "parameter `{0}' of method `{1}' must match " +
+                                               "the constraints for type parameter `{2}' " +
+                                               "of interface method `{3}'.  Consider using " +
+                                               "an explicit interface implementation instead",
+                                               Name, TypeManager.CSharpSignature (builder),
+                                               mparam, TypeManager.CSharpSignature (mb));
+                                       return false;
+                               }
+                       } else {
+                               if (constraints != null) {
+                                       if (!constraints.ResolveTypes (ec))
+                                               return false;
+                               }
+
+                               gc = (GenericConstraints) constraints;
+                       }
+
+                       if (gc == null)
+                               return true;
+
+                       if (gc.HasClassConstraint)
+                               type.SetBaseTypeConstraint (gc.ClassConstraint);
+
+                       type.SetInterfaceConstraints (gc.InterfaceConstraints);
+                       TypeManager.RegisterBuilder (type, gc.InterfaceConstraints);
+
+                       return true;
+               }
+
+               public bool CheckDependencies (EmitContext ec)
+               {
+                       if (constraints != null)
+                               return constraints.CheckDependencies (ec);
+
+                       return true;
+               }
+
+               public override string DocCommentHeader {
+                       get {
+                               throw new InvalidOperationException (
+                                       "Unexpected attempt to get doc comment from " + this.GetType () + ".");
+                       }
+               }
+
+               //
+               // MemberContainer
+               //
+
+               public override bool Define ()
+               {
+                       return true;
+               }
+
+               protected override void VerifyObsoleteAttribute ()
+               { }
+
+               public override void ApplyAttributeBuilder (Attribute a,
+                                                           CustomAttributeBuilder cb)
+               { }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return (AttributeTargets) 0;
+                       }
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return new string [0];
+                       }
+               }
+
+               //
+               // IMemberContainer
+               //
+
+               string IMemberContainer.Name {
+                       get { return Name; }
+               }
+
+               MemberCache IMemberContainer.ParentCache {
+                       get { return null; }
+               }
+
+               bool IMemberContainer.IsInterface {
+                       get { return true; }
+               }
+
+               MemberList IMemberContainer.GetMembers (MemberTypes mt, BindingFlags bf)
+               {
+                       return FindMembers (mt, bf, null, null);
+               }
+
+               MemberCache IMemberContainer.MemberCache {
+                       get { return null; }
+               }
+
+               public MemberList FindMembers (MemberTypes mt, BindingFlags bf,
+                                              MemberFilter filter, object criteria)
+               {
+                       if (constraints == null)
+                               return MemberList.Empty;
+
+                       ArrayList members = new ArrayList ();
+
+                       GenericConstraints gc = (GenericConstraints) constraints;
+
+                       if (gc.HasClassConstraint) {
+                               MemberList list = TypeManager.FindMembers (
+                                       gc.ClassConstraint, mt, bf, filter, criteria);
+
+                               members.AddRange (list);
+                       }
+
+                       foreach (Type t in gc.InterfaceConstraints) {
+                               MemberList list = TypeManager.FindMembers (
+                                       t, mt, bf, filter, criteria);
+
+                               members.AddRange (list);
+                       }
+
+                       return new MemberList (members);
+               }
+
+               public bool IsSubclassOf (Type t)
+               {
+                       if (type.Equals (t))
+                               return true;
+
+                       if (constraints != null)
+                               return constraints.IsSubclassOf (t);
+
+                       return false;
+               }
+
+               public override string ToString ()
+               {
+                       return "TypeParameter[" + name + "]";
+               }
+
+               protected class InflatedConstraints : GenericConstraints
+               {
+                       GenericConstraints gc;
+                       Type base_type;
+                       Type class_constraint;
+                       Type[] iface_constraints;
+                       Type[] dargs;
+                       Type declaring;
+
+                       public InflatedConstraints (GenericConstraints gc, Type declaring)
+                       {
+                               this.gc = gc;
+                               this.declaring = declaring;
+
+                               dargs = TypeManager.GetTypeArguments (declaring);
+
+                               ArrayList list = new ArrayList ();
+                               if (gc.HasClassConstraint)
+                                       list.Add (inflate (gc.ClassConstraint));
+                               foreach (Type iface in gc.InterfaceConstraints)
+                                       list.Add (inflate (iface));
+
+                               bool has_class_constr = false;
+                               if (list.Count > 0) {
+                                       Type first = (Type) list [0];
+                                       has_class_constr = !first.IsInterface && !first.IsGenericParameter;
+                               }
+
+                               if ((list.Count > 0) && has_class_constr) {
+                                       class_constraint = (Type) list [0];
+                                       iface_constraints = new Type [list.Count - 1];
+                                       list.CopyTo (1, iface_constraints, 0, list.Count - 1);
+                               } else {
+                                       iface_constraints = new Type [list.Count];
+                                       list.CopyTo (iface_constraints, 0);
+                               }
+
+                               if (HasValueTypeConstraint)
+                                       base_type = TypeManager.value_type;
+                               else if (class_constraint != null)
+                                       base_type = class_constraint;
+                               else
+                                       base_type = TypeManager.object_type;
+                       }
+
+                       Type inflate (Type t)
+                       {
+                               if (t == null)
+                                       return null;
+                               if (t.IsGenericParameter)
+                                       return dargs [t.GenericParameterPosition];
+                               if (t.IsGenericInstance) {
+                                       t = t.GetGenericTypeDefinition ();
+                                       t = t.BindGenericParameters (dargs);
+                               }
+
+                               return t;
+                       }
+
+                       public override GenericParameterAttributes Attributes {
+                               get { return gc.Attributes; }
+                       }
+
+                       public override Type ClassConstraint {
+                               get { return class_constraint; }
+                       }
+
+                       public override Type EffectiveBaseClass {
+                               get { return base_type; }
+                       }
+
+                       public override Type[] InterfaceConstraints {
+                               get { return iface_constraints; }
+                       }
+               }
+       }
+
+       //
+       // This type represents a generic type parameter reference.
+       //
+       // These expressions are born in a fully resolved state.
+       //
+       public class TypeParameterExpr : TypeExpr {
+               TypeParameter type_parameter;
+
+               public override string Name {
+                       get {
+                               return type_parameter.Name;
+                       }
+               }
+
+               public TypeParameter TypeParameter {
+                       get {
+                               return type_parameter;
+                       }
+               }
+               
+               public TypeParameterExpr (TypeParameter type_parameter, Location loc)
+               {
+                       this.type_parameter = type_parameter;
+                       this.loc = loc;
+               }
+
+               protected override TypeExpr DoResolveAsTypeStep (EmitContext ec)
+               {
+                       type = type_parameter.Type;
+
+                       return this;
+               }
+
+               public override bool IsInterface {
+                       get { return false; }
+               }
+
+               public override bool CheckAccessLevel (DeclSpace ds)
+               {
+                       return true;
+               }
+
+               public void Error_CannotUseAsUnmanagedType (Location loc)
+               {
+                       Report.Error (-203, loc, "Can not use type parameter as unamanged type");
+               }
+       }
+
+       public class TypeArguments {
+               public readonly Location Location;
+               ArrayList args;
+               Type[] atypes;
+               int dimension;
+               bool has_type_args;
+               bool created;
+               
+               public TypeArguments (Location loc)
+               {
+                       args = new ArrayList ();
+                       this.Location = loc;
+               }
+
+               public TypeArguments (int dimension, Location loc)
+               {
+                       this.dimension = dimension;
+                       this.Location = loc;
+               }
+
+               public void Add (Expression type)
+               {
+                       if (created)
+                               throw new InvalidOperationException ();
+
+                       args.Add (type);
+               }
+
+               public void Add (TypeArguments new_args)
+               {
+                       if (created)
+                               throw new InvalidOperationException ();
+
+                       args.AddRange (new_args.args);
+               }
+
+               public string[] GetDeclarations ()
+               {
+                       string[] ret = new string [args.Count];
+                       for (int i = 0; i < args.Count; i++) {
+                               SimpleName sn = args [i] as SimpleName;
+                               if (sn != null) {
+                                       ret [i] = sn.Name;
+                                       continue;
+                               }
+
+                               Report.Error (81, Location, "Type parameter declaration " +
+                                             "must be an identifier not a type");
+                               return null;
+                       }
+                       return ret;
+               }
+
+               public Type[] Arguments {
+                       get {
+                               return atypes;
+                       }
+               }
+
+               public bool HasTypeArguments {
+                       get {
+                               return has_type_args;
+                       }
+               }
+
+               public int Count {
+                       get {
+                               if (dimension > 0)
+                                       return dimension;
+                               else
+                                       return args.Count;
+                       }
+               }
+
+               public bool IsUnbound {
+                       get {
+                               return dimension > 0;
+                       }
+               }
+
+               public override string ToString ()
+               {
+                       StringBuilder s = new StringBuilder ();
+
+                       int count = Count;
+                       for (int i = 0; i < count; i++){
+                               //
+                               // FIXME: Use TypeManager.CSharpname once we have the type
+                               //
+                               if (args != null)
+                                       s.Append (args [i].ToString ());
+                               if (i+1 < count)
+                                       s.Append (",");
+                       }
+                       return s.ToString ();
+               }
+
+               public bool Resolve (EmitContext ec)
+               {
+                       DeclSpace ds = ec.DeclSpace;
+                       int count = args.Count;
+                       bool ok = true;
+
+                       atypes = new Type [count];
+
+                       for (int i = 0; i < count; i++){
+                               TypeExpr te = ((Expression) args [i]).ResolveAsTypeTerminal (ec);
+                               if (te == null) {
+                                       ok = false;
+                                       continue;
+                               }
+                               if (te is TypeParameterExpr)
+                                       has_type_args = true;
+
+                               atypes [i] = te.Type;
+                       }
+                       return ok;
+               }
+       }
+       
+       public class ConstructedType : TypeExpr {
+               string name, full_name;
+               TypeArguments args;
+               Type[] gen_params, atypes;
+               Type gt;
+               
+               public ConstructedType (string name, TypeArguments args, Location l)
+               {
+                       loc = l;
+                       this.name = MemberName.MakeName (name, args.Count);
+                       this.args = args;
+
+                       eclass = ExprClass.Type;
+                       full_name = name + "<" + args.ToString () + ">";
+               }
+
+               public ConstructedType (string name, TypeParameter[] type_params, Location l)
+                       : this (type_params, l)
+               {
+                       loc = l;
+
+                       this.name = name;
+                       full_name = name + "<" + args.ToString () + ">";
+               }
+
+               protected ConstructedType (TypeArguments args, Location l)
+               {
+                       loc = l;
+                       this.args = args;
+
+                       eclass = ExprClass.Type;
+               }
+
+               protected ConstructedType (TypeParameter[] type_params, Location l)
+               {
+                       loc = l;
+
+                       args = new TypeArguments (l);
+                       foreach (TypeParameter type_param in type_params)
+                               args.Add (new TypeParameterExpr (type_param, l));
+
+                       eclass = ExprClass.Type;
+               }
+
+               public ConstructedType (Type t, TypeParameter[] type_params, Location l)
+                       : this (type_params, l)
+               {
+                       gt = t.GetGenericTypeDefinition ();
+
+                       this.name = gt.FullName;
+                       full_name = gt.FullName + "<" + args.ToString () + ">";
+               }
+
+               public ConstructedType (Type t, TypeArguments args, Location l)
+                       : this (args, l)
+               {
+                       gt = t.GetGenericTypeDefinition ();
+
+                       this.name = gt.FullName;
+                       full_name = gt.FullName + "<" + args.ToString () + ">";
+               }
+
+               public TypeArguments TypeArguments {
+                       get { return args; }
+               }
+
+               protected string DeclarationName {
+                       get {
+                               StringBuilder sb = new StringBuilder ();
+                               sb.Append (gt.FullName);
+                               sb.Append ("<");
+                               for (int i = 0; i < gen_params.Length; i++) {
+                                       if (i > 0)
+                                               sb.Append (",");
+                                       sb.Append (gen_params [i]);
+                               }
+                               sb.Append (">");
+                               return sb.ToString ();
+                       }
+               }
+
+               protected bool CheckConstraint (EmitContext ec, Type ptype, Expression expr,
+                                               Type ctype)
+               {
+                       if (TypeManager.HasGenericArguments (ctype)) {
+                               Type[] types = TypeManager.GetTypeArguments (ctype);
+
+                               TypeArguments new_args = new TypeArguments (loc);
+
+                               for (int i = 0; i < types.Length; i++) {
+                                       Type t = types [i];
+
+                                       if (t.IsGenericParameter) {
+                                               int pos = t.GenericParameterPosition;
+                                               t = args.Arguments [pos];
+                                       }
+                                       new_args.Add (new TypeExpression (t, loc));
+                               }
+
+                               TypeExpr ct = new ConstructedType (ctype, new_args, loc);
+                               if (ct.ResolveAsTypeTerminal (ec) == null)
+                                       return false;
+                               ctype = ct.Type;
+                       }
+
+                       return Convert.ImplicitStandardConversionExists (ec, expr, ctype);
+               }
+
+               protected bool CheckConstraints (EmitContext ec, int index)
+               {
+                       Type atype = atypes [index];
+                       Type ptype = gen_params [index];
+
+                       if (atype == ptype)
+                               return true;
+
+                       Expression aexpr = new EmptyExpression (atype);
+
+                       GenericConstraints gc = TypeManager.GetTypeParameterConstraints (ptype);
+                       if (gc == null)
+                               return true;
+
+                       //
+                       // First, check the `class' and `struct' constraints.
+                       //
+                       if (gc.HasReferenceTypeConstraint && !atype.IsClass) {
+                               Report.Error (452, loc, "The type `{0}' must be " +
+                                             "a reference type in order to use it " +
+                                             "as type parameter `{1}' in the " +
+                                             "generic type or method `{2}'.",
+                                             atype, ptype, DeclarationName);
+                               return false;
+                       } else if (gc.HasValueTypeConstraint && !atype.IsValueType) {
+                               Report.Error (453, loc, "The type `{0}' must be " +
+                                             "a value type in order to use it " +
+                                             "as type parameter `{1}' in the " +
+                                             "generic type or method `{2}'.",
+                                             atype, ptype, DeclarationName);
+                               return false;
+                       }
+
+                       //
+                       // The class constraint comes next.
+                       //
+                       if (gc.HasClassConstraint) {
+                               if (!CheckConstraint (ec, ptype, aexpr, gc.ClassConstraint)) {
+                                       Report.Error (309, loc, "The type `{0}' must be " +
+                                                     "convertible to `{1}' in order to " +
+                                                     "use it as parameter `{2}' in the " +
+                                                     "generic type or method `{3}'",
+                                                     atype, gc.ClassConstraint, ptype, DeclarationName);
+                                       return false;
+                               }
+                       }
+
+                       //
+                       // Now, check the interface constraints.
+                       //
+                       foreach (Type it in gc.InterfaceConstraints) {
+                               Type itype;
+                               if (it.IsGenericParameter)
+                                       itype = atypes [it.GenericParameterPosition];
+                               else
+                                       itype = it;
+
+                               if (!CheckConstraint (ec, ptype, aexpr, itype)) {
+                                       Report.Error (309, loc, "The type `{0}' must be " +
+                                                     "convertible to `{1}' in order to " +
+                                                     "use it as parameter `{2}' in the " +
+                                                     "generic type or method `{3}'",
+                                                     atype, itype, ptype, DeclarationName);
+                                       return false;
+                               }
+                       }
+
+                       //
+                       // Finally, check the constructor constraint.
+                       //
+
+                       if (!gc.HasConstructorConstraint)
+                               return true;
+
+                       if (TypeManager.IsBuiltinType (atype) || atype.IsValueType)
+                               return true;
+
+                       MethodGroupExpr mg = Expression.MemberLookup (
+                               ec, atype, ".ctor", MemberTypes.Constructor,
+                               BindingFlags.Public | BindingFlags.Instance |
+                               BindingFlags.DeclaredOnly, loc)
+                               as MethodGroupExpr;
+
+                       if (atype.IsAbstract || (mg == null) || !mg.IsInstance) {
+                               Report.Error (310, loc, "The type `{0}' must have a public " +
+                                             "parameterless constructor in order to use it " +
+                                             "as parameter `{1}' in the generic type or " +
+                                             "method `{2}'", atype, ptype, DeclarationName);
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               protected override TypeExpr DoResolveAsTypeStep (EmitContext ec)
+               {
+                       if (!ResolveConstructedType (ec))
+                               return null;
+
+                       return this;
+               }
+
+               public bool CheckConstraints (EmitContext ec)
+               {
+                       for (int i = 0; i < gen_params.Length; i++) {
+                               if (!CheckConstraints (ec, i))
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               public override TypeExpr ResolveAsTypeTerminal (EmitContext ec)
+               {
+                       if (base.ResolveAsTypeTerminal (ec) == null)
+                               return null;
+
+                       if (!CheckConstraints (ec))
+                               return null;
+
+                       return this;
+               }
+
+               public bool ResolveConstructedType (EmitContext ec)
+               {
+                       if (type != null)
+                               return true;
+                       if (gt != null)
+                               return DoResolveType (ec);
+
+                       //
+                       // First, resolve the generic type.
+                       //
+                       DeclSpace ds;
+                       Type nested = ec.DeclSpace.FindNestedType (loc, name, out ds);
+                       if (nested != null) {
+                               gt = nested.GetGenericTypeDefinition ();
+
+                               TypeArguments new_args = new TypeArguments (loc);
+                               if (ds.IsGeneric) {
+                                       foreach (TypeParameter param in ds.TypeParameters)
+                                               new_args.Add (new TypeParameterExpr (param, loc));
+                               }
+                               new_args.Add (args);
+
+                               args = new_args;
+                               return DoResolveType (ec);
+                       }
+
+                       Type t;
+                       int num_args;
+
+                       SimpleName sn = new SimpleName (name, loc);
+                       TypeExpr resolved = sn.ResolveAsTypeTerminal (ec);
+                       if (resolved == null)
+                               return false;
+
+                       t = resolved.Type;
+                       if (t == null) {
+                               Report.Error (246, loc, "Cannot find type `{0}'<...>",
+                                             Basename);
+                               return false;
+                       }
+
+                       num_args = TypeManager.GetNumberOfTypeArguments (t);
+                       if (num_args == 0) {
+                               Report.Error (308, loc,
+                                             "The non-generic type `{0}' cannot " +
+                                             "be used with type arguments.",
+                                             TypeManager.CSharpName (t));
+                               return false;
+                       }
+
+                       gt = t.GetGenericTypeDefinition ();
+                       return DoResolveType (ec);
+               }
+
+               bool DoResolveType (EmitContext ec)
+               {
+                       //
+                       // Resolve the arguments.
+                       //
+                       if (args.Resolve (ec) == false)
+                               return false;
+
+                       gen_params = gt.GetGenericArguments ();
+                       atypes = args.Arguments;
+
+                       if (atypes.Length != gen_params.Length) {
+                               Report.Error (305, loc,
+                                             "Using the generic type `{0}' " +
+                                             "requires {1} type arguments",
+                                             TypeManager.GetFullName (gt),
+                                             gen_params.Length);
+                               return false;
+                       }
+
+                       //
+                       // Now bind the parameters.
+                       //
+                       type = gt.BindGenericParameters (atypes);
+                       return true;
+               }
+
+               public Expression GetSimpleName (EmitContext ec)
+               {
+                       return new SimpleName (Basename, args, loc);
+               }
+
+               public override bool CheckAccessLevel (DeclSpace ds)
+               {
+                       return ds.CheckAccessLevel (gt);
+               }
+
+               public override bool AsAccessible (DeclSpace ds, int flags)
+               {
+                       return ds.AsAccessible (gt, flags);
+               }
+
+               public override bool IsClass {
+                       get { return gt.IsClass; }
+               }
+
+               public override bool IsValueType {
+                       get { return gt.IsValueType; }
+               }
+
+               public override bool IsInterface {
+                       get { return gt.IsInterface; }
+               }
+
+               public override bool IsSealed {
+                       get { return gt.IsSealed; }
+               }
+
+               public override bool IsAttribute {
+                       get { return false; }
+               }
+
+               public override bool Equals (object obj)
+               {
+                       ConstructedType cobj = obj as ConstructedType;
+                       if (cobj == null)
+                               return false;
+
+                       if ((type == null) || (cobj.type == null))
+                               return false;
+
+                       return type == cobj.type;
+               }
+
+               public string Basename {
+                       get {
+                               int pos = name.LastIndexOf ('`');
+                               if (pos >= 0)
+                                       return name.Substring (0, pos);
+                               else
+                                       return name;
+                       }
+               }
+
+               public override string Name {
+                       get {
+                               return full_name;
+                       }
+               }
+       }
+
+       public class GenericMethod : DeclSpace
+       {
+               public GenericMethod (NamespaceEntry ns, TypeContainer parent,
+                                     MemberName name, Location l)
+                       : base (ns, parent, name, null, l)
+               { }
+
+               public override TypeBuilder DefineType ()
+               {
+                       throw new Exception ();
+               }
+
+               public override bool Define ()
+               {
+                       for (int i = 0; i < TypeParameters.Length; i++)
+                               if (!TypeParameters [i].Resolve (Parent))
+                                       return false;
+
+                       return true;
+               }
+
+               public bool Define (MethodBuilder mb, Type return_type)
+               {
+                       if (!Define ())
+                               return false;
+
+                       GenericTypeParameterBuilder[] gen_params;
+                       string[] names = MemberName.TypeArguments.GetDeclarations ();
+                       gen_params = mb.DefineGenericParameters (names);
+                       for (int i = 0; i < TypeParameters.Length; i++)
+                               TypeParameters [i].Define (gen_params [i]);
+
+                       ec = new EmitContext (
+                               this, this, Location, null, return_type, ModFlags, false);
+
+                       return true;
+               }
+
+               public bool DefineType (EmitContext ec, MethodBuilder mb,
+                                       MethodInfo implementing, bool is_override)
+               {
+                       for (int i = 0; i < TypeParameters.Length; i++)
+                               if (!TypeParameters [i].DefineType (
+                                           ec, mb, implementing, is_override))
+                                       return false;
+
+                       return true;
+               }
+
+               public override bool DefineMembers (TypeContainer parent)
+               {
+                       return true;
+               }
+
+               public override MemberList FindMembers (MemberTypes mt, BindingFlags bf,
+                                                       MemberFilter filter, object criteria)
+               {
+                       throw new Exception ();
+               }               
+
+               public override MemberCache MemberCache {
+                       get {
+                               throw new Exception ();
+                       }
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       // FIXME
+               }
+
+               protected override void VerifyObsoleteAttribute()
+               {
+                       // FIXME
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Method | AttributeTargets.ReturnValue;
+                       }
+               }
+
+               public override string DocCommentHeader {
+                       get { return "M:"; }
+               }
+       }
+
+       public class DefaultValueExpression : Expression
+       {
+               Expression expr;
+               LocalTemporary temp_storage;
+
+               public DefaultValueExpression (Expression expr, Location loc)
+               {
+                       this.expr = expr;
+                       this.loc = loc;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       TypeExpr texpr = expr.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return null;
+
+                       type = texpr.Type;
+                       if (type.IsGenericParameter || TypeManager.IsValueType (type))
+                               temp_storage = new LocalTemporary (ec, type);
+
+                       eclass = ExprClass.Variable;
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       if (temp_storage != null) {
+                               temp_storage.AddressOf (ec, AddressOp.LoadStore);
+                               ec.ig.Emit (OpCodes.Initobj, type);
+                               temp_storage.Emit (ec);
+                       } else
+                               ec.ig.Emit (OpCodes.Ldnull);
+               }
+       }
+
+       public partial class TypeManager
+       {
+               //
+               // A list of core types that the compiler requires or uses
+               //
+               static public Type new_constraint_attr_type;
+               static public Type activator_type;
+               static public Type generic_ienumerator_type;
+               static public Type generic_ienumerable_type;
+
+               // <remarks>
+               //   Tracks the generic parameters.
+               // </remarks>
+               static PtrHashtable builder_to_type_param;
+
+               //
+               // These methods are called by code generated by the compiler
+               //
+               static public MethodInfo activator_create_instance;
+
+               static void InitGenerics ()
+               {
+                       builder_to_type_param = new PtrHashtable ();
+               }
+
+               static void CleanUpGenerics ()
+               {
+                       builder_to_type_param = null;
+               }
+
+               static void InitGenericCoreTypes ()
+               {
+                       activator_type = CoreLookupType ("System.Activator");
+                       new_constraint_attr_type = CoreLookupType (
+                               "System.Runtime.CompilerServices.NewConstraintAttribute");
+
+                       generic_ienumerator_type = CoreLookupType (
+                               MemberName.MakeName ("System.Collections.Generic.IEnumerator", 1));
+                       generic_ienumerable_type = CoreLookupType (
+                               MemberName.MakeName ("System.Collections.Generic.IEnumerable", 1));
+               }
+
+               static void InitGenericCodeHelpers ()
+               {
+                       // Activator
+                       Type [] type_arg = { type_type };
+                       activator_create_instance = GetMethod (
+                               activator_type, "CreateInstance", type_arg);
+               }
+
+               public static void AddTypeParameter (Type t, TypeParameter tparam)
+               {
+                       if (!builder_to_type_param.Contains (t))
+                               builder_to_type_param.Add (t, tparam);
+               }
+
+               public static TypeContainer LookupGenericTypeContainer (Type t)
+               {
+                       while (t.IsGenericInstance)
+                               t = t.GetGenericTypeDefinition ();
+
+                       return LookupTypeContainer (t);
+               }
+
+               public static TypeParameter LookupTypeParameter (Type t)
+               {
+                       return (TypeParameter) builder_to_type_param [t];
+               }
+
+               public static bool HasConstructorConstraint (Type t)
+               {
+                       GenericConstraints gc = GetTypeParameterConstraints (t);
+                       if (gc == null)
+                               return false;
+
+                       return (gc.Attributes & GenericParameterAttributes.DefaultConstructorConstraint) != 0;
+               }
+
+               public static GenericConstraints GetTypeParameterConstraints (Type t)
+               {
+                       if (!t.IsGenericParameter)
+                               throw new InvalidOperationException ();
+
+                       TypeParameter tparam = LookupTypeParameter (t);
+                       if (tparam != null)
+                               return tparam.GenericConstraints;
+
+                       return new ReflectionConstraints (t);
+               }
+
+               public static bool IsGeneric (Type t)
+               {
+                       DeclSpace ds = (DeclSpace) builder_to_declspace [t];
+
+                       return ds.IsGeneric;
+               }
+
+               public static bool HasGenericArguments (Type t)
+               {
+                       return GetNumberOfTypeArguments (t) > 0;
+               }
+
+               public static int GetNumberOfTypeArguments (Type t)
+               {
+                       DeclSpace tc = LookupDeclSpace (t);
+                       if (tc != null)
+                               return tc.IsGeneric ? tc.CountTypeParameters : 0;
+                       else
+                               return t.HasGenericArguments ? t.GetGenericArguments ().Length : 0;
+               }
+
+               public static Type[] GetTypeArguments (Type t)
+               {
+                       DeclSpace tc = LookupDeclSpace (t);
+                       if (tc != null) {
+                               if (!tc.IsGeneric)
+                                       return Type.EmptyTypes;
+
+                               TypeParameter[] tparam = tc.TypeParameters;
+                               Type[] ret = new Type [tparam.Length];
+                               for (int i = 0; i < tparam.Length; i++) {
+                                       ret [i] = tparam [i].Type;
+                                       if (ret [i] == null)
+                                               throw new InternalErrorException ();
+                               }
+
+                               return ret;
+                       } else
+                               return t.GetGenericArguments ();
+               }
+
+               public static bool IsEqual (Type a, Type b)
+               {
+                       if (a.Equals (b))
+                               return true;
+
+                       if ((a is TypeBuilder) && a.IsGenericTypeDefinition && b.IsGenericInstance) {
+                               //
+                               // `a' is a generic type definition's TypeBuilder and `b' is a
+                               // generic instance of the same type.
+                               //
+                               // Example:
+                               //
+                               // class Stack<T>
+                               // {
+                               //     void Test (Stack<T> stack) { }
+                               // }
+                               //
+                               // The first argument of `Test' will be the generic instance
+                               // "Stack<!0>" - which is the same type than the "Stack" TypeBuilder.
+                               //
+                               //
+                               // We hit this via Closure.Filter() for gen-82.cs.
+                               //
+                               if (a != b.GetGenericTypeDefinition ())
+                                       return false;
+
+                               Type[] aparams = a.GetGenericArguments ();
+                               Type[] bparams = b.GetGenericArguments ();
+
+                               if (aparams.Length != bparams.Length)
+                                       return false;
+
+                               for (int i = 0; i < aparams.Length; i++)
+                                       if (!IsEqual (aparams [i], bparams [i]))
+                                               return false;
+
+                               return true;
+                       }
+
+                       if (a.IsGenericParameter && b.IsGenericParameter) {
+                               if ((a.DeclaringMethod == null) || (b.DeclaringMethod == null))
+                                       return false;
+                               return a.GenericParameterPosition == b.GenericParameterPosition;
+                       }
+
+                       if (a.IsArray && b.IsArray) {
+                               if (a.GetArrayRank () != b.GetArrayRank ())
+                                       return false;
+                               return IsEqual (a.GetElementType (), b.GetElementType ());
+                       }
+
+                       if (a.IsGenericInstance && b.IsGenericInstance) {
+                               Type at = a.GetGenericTypeDefinition ();
+                               Type bt = b.GetGenericTypeDefinition ();
+
+                               if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
+                                       return false;
+
+                               Type[] aargs = a.GetGenericArguments ();
+                               Type[] bargs = b.GetGenericArguments ();
+
+                               if (aargs.Length != bargs.Length)
+                                       return false;
+
+                               for (int i = 0; i < aargs.Length; i++) {
+                                       if (!IsEqual (aargs [i], bargs [i]))
+                                               return false;
+                               }
+
+                               return true;
+                       }
+
+                       return false;
+               }
+
+               public static bool MayBecomeEqualGenericTypes (Type a, Type b, Type[] class_infered, Type[] method_infered)
+               {
+                       if (a.IsGenericParameter) {
+                               //
+                               // If a is an array of a's type, they may never
+                               // become equal.
+                               //
+                               while (b.IsArray) {
+                                       b = b.GetElementType ();
+                                       if (a.Equals (b))
+                                               return false;
+                               }
+
+                               //
+                               // If b is a generic parameter or an actual type,
+                               // they may become equal:
+                               //
+                               //    class X<T,U> : I<T>, I<U>
+                               //    class X<T> : I<T>, I<float>
+                               // 
+                               if (b.IsGenericParameter || !b.IsGenericInstance) {
+                                       int pos = a.GenericParameterPosition;
+                                       Type[] args = a.DeclaringMethod != null ? method_infered : class_infered;
+                                       if (args [pos] == null) {
+                                               args [pos] = b;
+                                               return true;
+                                       }
+
+                                       return args [pos] == a;
+                               }
+
+                               //
+                               // We're now comparing a type parameter with a
+                               // generic instance.  They may become equal unless
+                               // the type parameter appears anywhere in the
+                               // generic instance:
+                               //
+                               //    class X<T,U> : I<T>, I<X<U>>
+                               //        -> error because you could instanciate it as
+                               //           X<X<int>,int>
+                               //
+                               //    class X<T> : I<T>, I<X<T>> -> ok
+                               //
+
+                               Type[] bargs = GetTypeArguments (b);
+                               for (int i = 0; i < bargs.Length; i++) {
+                                       if (a.Equals (bargs [i]))
+                                               return false;
+                               }
+
+                               return true;
+                       }
+
+                       if (b.IsGenericParameter)
+                               return MayBecomeEqualGenericTypes (b, a, class_infered, method_infered);
+
+                       //
+                       // At this point, neither a nor b are a type parameter.
+                       //
+                       // If one of them is a generic instance, let
+                       // MayBecomeEqualGenericInstances() compare them (if the
+                       // other one is not a generic instance, they can never
+                       // become equal).
+                       //
+
+                       if (a.IsGenericInstance || b.IsGenericInstance)
+                               return MayBecomeEqualGenericInstances (a, b, class_infered, method_infered);
+
+                       //
+                       // If both of them are arrays.
+                       //
+
+                       if (a.IsArray && b.IsArray) {
+                               if (a.GetArrayRank () != b.GetArrayRank ())
+                                       return false;
+                       
+                               a = a.GetElementType ();
+                               b = b.GetElementType ();
+
+                               return MayBecomeEqualGenericTypes (a, b, class_infered, method_infered);
+                       }
+
+                       //
+                       // Ok, two ordinary types.
+                       //
+
+                       return a.Equals (b);
+               }
+
+               //
+               // Checks whether two generic instances may become equal for some
+               // particular instantiation (26.3.1).
+               //
+               public static bool MayBecomeEqualGenericInstances (Type a, Type b,
+                                                                  Type[] class_infered, Type[] method_infered)
+               {
+                       if (!a.IsGenericInstance || !b.IsGenericInstance)
+                               return false;
+                       if (a.GetGenericTypeDefinition () != b.GetGenericTypeDefinition ())
+                               return false;
+
+                       Type[] aargs = GetTypeArguments (a);
+                       Type[] bargs = GetTypeArguments (b);
+
+                       return MayBecomeEqualGenericInstances (
+                               GetTypeArguments (a), GetTypeArguments (b), class_infered, method_infered);
+               }
+
+               public static bool MayBecomeEqualGenericInstances (Type[] aargs, Type[] bargs,
+                                                                  Type[] class_infered, Type[] method_infered)
+               {
+                       if (aargs.Length != bargs.Length)
+                               return false;
+
+                       Type[] args = new Type [aargs.Length];
+                       for (int i = 0; i < aargs.Length; i++) {
+                               if (!MayBecomeEqualGenericTypes (aargs [i], bargs [i], class_infered, method_infered))
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               public static bool IsEqualGenericInstance (Type type, Type parent)
+               {
+                       int tcount = GetNumberOfTypeArguments (type);
+                       int pcount = GetNumberOfTypeArguments (parent);
+
+                       if (type.IsGenericInstance)
+                               type = type.GetGenericTypeDefinition ();
+                       if (parent.IsGenericInstance)
+                               parent = parent.GetGenericTypeDefinition ();
+
+                       if (tcount != pcount)
+                               return false;
+
+                       return type.Equals (parent);
+               }
+
+               static public bool IsGenericMethod (MethodBase mb)
+               {
+                       if (mb.DeclaringType is TypeBuilder) {
+                               IMethodData method = (IMethodData) builder_to_method [mb];
+                               if (method == null)
+                                       return false;
+
+                               return method.GenericMethod != null;
+                       }
+
+                       return mb.IsGenericMethodDefinition;
+               }
+
+               //
+               // Type inference.
+               //
+
+               static bool InferType (Type pt, Type at, Type[] infered)
+               {
+                       if (pt.IsGenericParameter && (pt.DeclaringMethod != null)) {
+                               int pos = pt.GenericParameterPosition;
+
+                               if (infered [pos] == null) {
+                                       Type check = at;
+                                       while (check.IsArray)
+                                               check = check.GetElementType ();
+
+                                       if (pt == check)
+                                               return false;
+
+                                       infered [pos] = at;
+                                       return true;
+                               }
+
+                               if (infered [pos] != at)
+                                       return false;
+
+                               return true;
+                       }
+
+                       if (!pt.ContainsGenericParameters) {
+                               if (at.ContainsGenericParameters)
+                                       return InferType (at, pt, infered);
+                               else
+                                       return true;
+                       }
+
+                       if (at.IsArray) {
+                               if (!pt.IsArray ||
+                                   (at.GetArrayRank () != pt.GetArrayRank ()))
+                                       return false;
+
+                               return InferType (pt.GetElementType (), at.GetElementType (), infered);
+                       }
+
+                       if (pt.IsArray) {
+                               if (!at.IsArray ||
+                                   (pt.GetArrayRank () != at.GetArrayRank ()))
+                                       return false;
+
+                               return InferType (pt.GetElementType (), at.GetElementType (), infered);
+                       }
+
+                       if (pt.IsByRef && at.IsByRef)
+                               return InferType (pt.GetElementType (), at.GetElementType (), infered);
+                       ArrayList list = new ArrayList ();
+                       if (at.IsGenericInstance)
+                               list.Add (at);
+                       else {
+                               for (Type bt = at.BaseType; bt != null; bt = bt.BaseType)
+                                       list.Add (bt);
+
+                               list.AddRange (TypeManager.GetInterfaces (at));
+                       }
+
+                       bool found_one = false;
+
+                       foreach (Type type in list) {
+                               if (!type.IsGenericInstance)
+                                       continue;
+
+                               Type[] infered_types = new Type [infered.Length];
+
+                               if (!InferGenericInstance (pt, type, infered_types))
+                                       continue;
+
+                               for (int i = 0; i < infered_types.Length; i++) {
+                                       if (infered [i] == null) {
+                                               infered [i] = infered_types [i];
+                                               continue;
+                                       }
+
+                                       if (infered [i] != infered_types [i])
+                                               return false;
+                               }
+
+                               found_one = true;
+                       }
+
+                       return found_one;
+               }
+
+               static bool InferGenericInstance (Type pt, Type at, Type[] infered_types)
+               {
+                       Type[] at_args = at.GetGenericArguments ();
+                       Type[] pt_args = pt.GetGenericArguments ();
+
+                       if (at_args.Length != pt_args.Length)
+                               return false;
+
+                       for (int i = 0; i < at_args.Length; i++) {
+                               if (!InferType (pt_args [i], at_args [i], infered_types))
+                                       return false;
+                       }
+
+                       for (int i = 0; i < infered_types.Length; i++) {
+                               if (infered_types [i] == null)
+                                       return false;
+                       }
+
+                       return true;
+               }
+
+               public static bool InferParamsTypeArguments (EmitContext ec, ArrayList arguments,
+                                                            ref MethodBase method)
+               {
+                       if ((arguments == null) || !TypeManager.IsGenericMethod (method))
+                               return true;
+
+                       int arg_count;
+                       
+                       if (arguments == null)
+                               arg_count = 0;
+                       else
+                               arg_count = arguments.Count;
+                       
+                       ParameterData pd = Invocation.GetParameterData (method);
+
+                       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;
+
+                       Type[] method_args = method.GetGenericArguments ();
+                       Type[] infered_types = new Type [method_args.Length];
+
+                       //
+                       // 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];
+
+                               if ((a.Expr is NullLiteral) || (a.Expr is MethodGroupExpr))
+                                       continue;
+
+                               Type pt = pd.ParameterType (i);
+                               Type at = a.Type;
+
+                               if (!InferType (pt, at, infered_types))
+                                       return false;
+                       }
+
+                       Type element_type = TypeManager.GetElementType (pd.ParameterType (pd_count - 1));
+
+                       for (int i = pd_count - 1; i < arg_count; i++) {
+                               Argument a = (Argument) arguments [i];
+
+                               if ((a.Expr is NullLiteral) || (a.Expr is MethodGroupExpr))
+                                       continue;
+
+                               if (!InferType (element_type, a.Type, infered_types))
+                                       return false;
+                       }
+
+                       for (int i = 0; i < infered_types.Length; i++)
+                               if (infered_types [i] == null)
+                                       return false;
+
+                       method = method.BindGenericParameters (infered_types);
+                       return true;
+               }
+
+               public static bool InferTypeArguments (Type[] param_types, Type[] arg_types, Type[] infered_types)
+               {
+                       if (infered_types == null)
+                               return false;
+
+                       for (int i = 0; i < arg_types.Length; i++) {
+                               if (arg_types [i] == null)
+                                       continue;
+
+                               if (!InferType (param_types [i], arg_types [i], infered_types))
+                                       return false;
+                       }
+
+                       for (int i = 0; i < infered_types.Length; i++)
+                               if (infered_types [i] == null)
+                                       return false;
+
+                       return true;
+               }
+
+               public static bool InferTypeArguments (EmitContext ec, ArrayList arguments,
+                                                      ref MethodBase method)
+               {
+                       if (!TypeManager.IsGenericMethod (method))
+                               return true;
+
+                       int arg_count;
+                       if (arguments != null)
+                               arg_count = arguments.Count;
+                       else
+                               arg_count = 0;
+
+                       ParameterData pd = Invocation.GetParameterData (method);
+                       if (arg_count != pd.Count)
+                               return false;
+
+                       Type[] method_args = method.GetGenericArguments ();
+
+                       bool is_open = false;
+                       for (int i = 0; i < method_args.Length; i++) {
+                               if (method_args [i].IsGenericParameter) {
+                                       is_open = true;
+                                       break;
+                               }
+                       }
+                       if (!is_open)
+                               return true;
+
+                       Type[] infered_types = new Type [method_args.Length];
+
+                       Type[] param_types = new Type [pd.Count];
+                       Type[] arg_types = new Type [pd.Count];
+
+                       for (int i = 0; i < arg_count; i++) {
+                               param_types [i] = pd.ParameterType (i);
+
+                               Argument a = (Argument) arguments [i];
+                               if ((a.Expr is NullLiteral) || (a.Expr is MethodGroupExpr))
+                                       continue;
+
+                               arg_types [i] = a.Type;
+                       }
+
+                       if (!InferTypeArguments (param_types, arg_types, infered_types))
+                               return false;
+
+                       method = method.BindGenericParameters (infered_types);
+                       return true;
+               }
+
+               public static bool InferTypeArguments (EmitContext ec, ParameterData apd,
+                                                      ref MethodBase method)
+               {
+                       if (!TypeManager.IsGenericMethod (method))
+                               return true;
+
+                       ParameterData pd = Invocation.GetParameterData (method);
+                       if (apd.Count != pd.Count)
+                               return false;
+
+                       Type[] method_args = method.GetGenericArguments ();
+                       Type[] infered_types = new Type [method_args.Length];
+
+                       Type[] param_types = new Type [pd.Count];
+                       Type[] arg_types = new Type [pd.Count];
+
+                       for (int i = 0; i < apd.Count; i++) {
+                               param_types [i] = pd.ParameterType (i);
+                               arg_types [i] = apd.ParameterType (i);
+                       }
+
+                       if (!InferTypeArguments (param_types, arg_types, infered_types))
+                               return false;
+
+                       method = method.BindGenericParameters (infered_types);
+                       return true;
+               }
+       }
+}
diff --git a/mcs/bmcs/gmcs.exe.sources b/mcs/bmcs/gmcs.exe.sources
new file mode 100644 (file)
index 0000000..f9782f4
--- /dev/null
@@ -0,0 +1,38 @@
+AssemblyInfo.cs
+anonymous.cs
+assign.cs
+attribute.cs
+driver.cs
+cs-tokenizer.cs
+cfold.cs
+class.cs
+codegen.cs
+const.cs
+constant.cs
+convert.cs
+decl.cs
+delegate.cs
+doc.cs
+enum.cs
+ecore.cs
+expression.cs
+flowanalysis.cs
+generic.cs
+iterators.cs
+literal.cs
+location.cs
+modifiers.cs
+namespace.cs
+parameter.cs
+pending.cs
+report.cs
+rootcontext.cs
+statement.cs
+support.cs
+typemanager.cs
+symbolwriter.cs
+tree.cs
+CryptoConvert.cs
+../class/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs
+../class/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs
+../class/Mono.CompilerServices.SymbolWriter/MonoSymbolWriter.cs
diff --git a/mcs/bmcs/iterators.cs b/mcs/bmcs/iterators.cs
new file mode 100644 (file)
index 0000000..98e3860
--- /dev/null
@@ -0,0 +1,1012 @@
+//
+// iterators.cs: Support for implementing iterators
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2003 Ximian, Inc.
+//
+// TODO:
+//    Flow analysis for Yield.
+//    Emit calls to parent object constructor.
+//
+// Generics note:
+//    Current should be defined to return T, and IEnumerator.Current returns object
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace Mono.CSharp {
+
+       public interface IIteratorContainer {
+
+               //
+               // Invoked if a yield statement is found in the body
+               //
+               void SetYields ();
+       }
+       
+       public class Yield : Statement {
+               public Expression expr;
+               ArrayList finally_blocks;
+               
+               public Yield (Expression expr, Location l)
+               {
+                       this.expr = expr;
+                       loc = l;
+               }
+
+               public static bool CheckContext (EmitContext ec, Location loc)
+               {
+                       if (ec.CurrentBranching.InFinally (true)){
+                               Report.Error (1625, loc, "Cannot yield in the body of a " +
+                                             "finally clause");
+                               return false;
+                       }
+                       if (ec.CurrentBranching.InCatch ()){
+                               Report.Error (1631, loc, "Cannot yield in the body of a " +
+                                             "catch clause");
+                               return false;
+                       }
+                       if (ec.CurrentAnonymousMethod != null){
+                               Report.Error (1621, loc, "yield statement can not appear inside an anonymoud method");
+                               return false;
+                       }
+
+                       //
+                       // FIXME: Missing check for Yield inside try block that contains catch clauses
+                       //
+                       return true;
+               }
+               
+               public override bool Resolve (EmitContext ec)
+               {
+                       expr = expr.Resolve (ec);
+                       if (expr == null)
+                               return false;
+                       if (!CheckContext (ec, loc))
+                               return false;
+
+                       Iterator iterator = ec.CurrentIterator;
+                       if (expr.Type != iterator.IteratorType){
+                               expr = Convert.ImplicitConversionRequired (
+                                       ec, expr, iterator.IteratorType, loc);
+                               if (expr == null)
+                                       return false;
+                       }
+
+                       ec.CurrentBranching.StealFinallyClauses (ref finally_blocks);
+                       return true;
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+                       ec.CurrentIterator.MarkYield (ec, expr, finally_blocks);
+               }
+       }
+
+       public class YieldBreak : Statement {
+
+               public YieldBreak (Location l)
+               {
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       if (!Yield.CheckContext (ec, loc))
+                               return false;
+
+                       ec.CurrentBranching.CurrentUsageVector.Goto ();
+                       return true;
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+                       ec.CurrentIterator.EmitYieldBreak (ec.ig);
+               }
+       }
+
+       public class Iterator : Class {
+               ToplevelBlock original_block;
+               ToplevelBlock block;
+               string original_name;
+
+               Type iterator_type;
+               TypeExpr iterator_type_expr;
+               bool is_enumerable;
+               bool is_static;
+
+               Hashtable fields;
+
+               //
+               // The state as we generate the iterator
+               //
+               Label move_next_ok, move_next_error;
+               ArrayList resume_points = new ArrayList ();
+               int pc;
+               
+               //
+               // Context from the original method
+               //
+               TypeContainer container;
+               TypeExpr current_type;
+               Type this_type;
+               Type return_type;
+               Type [] param_types;
+               InternalParameters parameters;
+
+               MethodInfo dispose_method;
+
+               Expression enumerator_type;
+               Expression enumerable_type;
+               Expression generic_enumerator_type;
+               Expression generic_enumerable_type;
+               TypeArguments generic_args;
+
+               protected enum State {
+                       Uninitialized   = -2,
+                       After,
+                       Running
+               }
+
+               static int proxy_count;
+
+               public void EmitYieldBreak (ILGenerator ig)
+               {
+                       ig.Emit (OpCodes.Ldarg_0);
+                       IntConstant.EmitInt (ig, (int) State.After);
+                       ig.Emit (OpCodes.Stfld, pc_field.FieldBuilder);
+                       ig.Emit (OpCodes.Br, move_next_error);
+               }
+
+               public void EmitMoveNext (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       move_next_ok = ig.DefineLabel ();
+                       move_next_error = ig.DefineLabel ();
+
+                       LocalBuilder retval = ec.GetTemporaryLocal (TypeManager.int32_type);
+
+                       ig.BeginExceptionBlock ();
+
+                       Label dispatcher = ig.DefineLabel ();
+                       ig.Emit (OpCodes.Br, dispatcher);
+
+                       ResumePoint entry_point = new ResumePoint (null);
+                       resume_points.Add (entry_point);
+                       entry_point.Define (ig);
+
+                       ec.EmitTopBlock (original_block, parameters, Location);
+                       EmitYieldBreak (ig);
+
+                       ig.MarkLabel (dispatcher);
+
+                       Label [] labels = new Label [resume_points.Count];
+                       for (int i = 0; i < labels.Length; i++)
+                               labels [i] = ((ResumePoint) resume_points [i]).Label;
+
+                       ig.Emit (OpCodes.Ldarg_0);
+                       ig.Emit (OpCodes.Ldfld, pc_field.FieldBuilder);
+                       ig.Emit (OpCodes.Switch, labels);
+
+                       Label end = ig.DefineLabel ();
+
+                       ig.MarkLabel (move_next_error);
+                       ig.Emit (OpCodes.Ldc_I4_0); 
+                       ig.Emit (OpCodes.Stloc, retval);
+                       ig.Emit (OpCodes.Leave, end);
+
+                       ig.MarkLabel (move_next_ok);
+                       ig.Emit (OpCodes.Ldc_I4_1);
+                       ig.Emit (OpCodes.Stloc, retval);
+                       ig.Emit (OpCodes.Leave, end);
+
+                       ig.BeginFaultBlock ();
+
+                       ig.Emit (OpCodes.Ldarg_0);
+                       ig.Emit (OpCodes.Callvirt, dispose_method);
+
+                       ig.EndExceptionBlock ();
+
+                       ig.MarkLabel (end);
+                       ig.Emit (OpCodes.Ldloc, retval);
+                       ig.Emit (OpCodes.Ret);
+               }
+
+               public void EmitDispose (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       Label end = ig.DefineLabel ();
+                       Label dispatcher = ig.DefineLabel ();
+                       ig.Emit (OpCodes.Br, dispatcher);
+
+                       ec.RemapToProxy = true;
+                       Label [] labels = new Label [resume_points.Count];
+                       for (int i = 0; i < labels.Length; i++) {
+                               ResumePoint point = (ResumePoint) resume_points [i];
+
+                               if (point.FinallyBlocks == null) {
+                                       labels [i] = end;
+                                       continue;
+                               }
+
+                               labels [i] = ig.DefineLabel ();
+                               ig.MarkLabel (labels [i]);
+
+                               ig.BeginExceptionBlock ();
+                               ig.BeginFinallyBlock ();
+
+                               foreach (ExceptionStatement stmt in point.FinallyBlocks) {
+                                       if (stmt != null)
+                                               stmt.EmitFinally (ec);
+                               }
+
+                               ig.EndExceptionBlock ();
+                               ig.Emit (OpCodes.Br, end);
+                       }
+                       ec.RemapToProxy = false;
+
+                       ig.MarkLabel (dispatcher);
+                       ig.Emit (OpCodes.Ldarg_0);
+                       ig.Emit (OpCodes.Ldfld, pc_field.FieldBuilder);
+                       ig.Emit (OpCodes.Switch, labels);
+
+                       ig.Emit (OpCodes.Ldarg_0);
+                       IntConstant.EmitInt (ig, (int) State.After);
+                       ig.Emit (OpCodes.Stfld, pc_field.FieldBuilder);
+
+                       ig.MarkLabel (end);
+               }
+
+               protected class ResumePoint
+               {
+                       public Label Label;
+                       public readonly ExceptionStatement[] FinallyBlocks;
+
+                       public ResumePoint (ArrayList list)
+                       {
+                               if (list != null) {
+                                       FinallyBlocks = new ExceptionStatement [list.Count];
+                                       list.CopyTo (FinallyBlocks, 0);
+                               }
+                       }
+
+                       public void Define (ILGenerator ig)
+                       {
+                               Label = ig.DefineLabel ();
+                               ig.MarkLabel (Label);
+                       }
+               }
+
+               // 
+               // Invoked when a local variable declaration needs to be mapped to
+               // a field in our proxy class
+               //
+               // Prefixes registered:
+               //   v_   for EmitContext.MapVariable
+               //   s_   for Storage
+               //
+               public FieldBuilder MapVariable (string pfx, string name, Type t)
+               {
+                       string full_name = pfx + name;
+                       FieldBuilder fb = (FieldBuilder) fields [full_name];
+                       if (fb != null)
+                               return fb;
+
+                       fb = TypeBuilder.DefineField (full_name, t, FieldAttributes.Private);
+                       fields.Add (full_name, fb);
+                       return fb;
+               }
+
+               //
+               // Called back from Yield
+               //
+               public void MarkYield (EmitContext ec, Expression expr,
+                                      ArrayList finally_blocks)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       // Store the new current
+                       ig.Emit (OpCodes.Ldarg_0);
+                       expr.Emit (ec);
+                       ig.Emit (OpCodes.Stfld, current_field.FieldBuilder);
+
+                       // increment pc
+                       pc++;
+                       ig.Emit (OpCodes.Ldarg_0);
+                       IntConstant.EmitInt (ig, pc);
+                       ig.Emit (OpCodes.Stfld, pc_field.FieldBuilder);
+
+                       // Return ok
+                       ig.Emit (OpCodes.Br, move_next_ok);
+
+                       ResumePoint point = new ResumePoint (finally_blocks);
+                       resume_points.Add (point);
+                       point.Define (ig);
+               }
+
+               public void MarkFinally (EmitContext ec, ArrayList finally_blocks)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       // increment pc
+                       pc++;
+                       ig.Emit (OpCodes.Ldarg_0);
+                       IntConstant.EmitInt (ig, pc);
+                       ig.Emit (OpCodes.Stfld, pc_field.FieldBuilder);
+
+                       ResumePoint point = new ResumePoint (finally_blocks);
+                       resume_points.Add (point);
+                       point.Define (ig);
+               }
+
+               private static MemberName MakeProxyName (string name)
+               {
+                       int pos = name.LastIndexOf ('.');
+                       if (pos > 0)
+                               name = name.Substring (pos + 1);
+
+                       return new MemberName ("<" + name + ">__" + (proxy_count++));
+               }
+
+               //
+               // Our constructor
+               //
+               public Iterator (TypeContainer container, string name, Type return_type,
+                                Type [] param_types, InternalParameters parameters,
+                                int modifiers, ToplevelBlock block, Location loc)
+                       : base (container.NamespaceEntry, container, MakeProxyName (name),
+                               Modifiers.PRIVATE, null, loc)
+               {
+                       this.container = container;
+                       this.return_type = return_type;
+                       this.param_types = param_types;
+                       this.parameters = parameters;
+                       this.original_name = name;
+                       this.original_block = block;
+                       this.block = new ToplevelBlock (loc);
+
+                       fields = new Hashtable ();
+
+                       is_static = (modifiers & Modifiers.STATIC) != 0;
+               }
+
+               public bool DefineIterator ()
+               {
+                       ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
+
+                       if (!CheckType (return_type)) {
+                               Report.Error (
+                                       1624, Location,
+                                       "The body of `{0}' cannot be an iterator block " +
+                                       "because '{1}' is not an iterator interface type",
+                                       original_name, TypeManager.CSharpName (return_type));
+                               return false;
+                       }
+
+                       for (int i = 0; i < parameters.Count; i++){
+                               Parameter.Modifier mod = parameters.ParameterModifier (i);
+                               if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0){
+                                       Report.Error (
+                                               1623, Location,
+                                               "Iterators cannot have ref or out parameters");
+                                       return false;
+                               }
+                       }
+
+                       if (container.CurrentType != null)
+                               this_type = container.CurrentType;
+                       else
+                               this_type = container.TypeBuilder;
+
+                       generic_args = new TypeArguments (Location);
+                       generic_args.Add (new TypeExpression (iterator_type, Location));
+
+                       ArrayList list = new ArrayList ();
+                       if (is_enumerable) {
+                               enumerable_type = new TypeExpression (
+                                       TypeManager.ienumerable_type, Location);
+                               list.Add (enumerable_type);
+
+                               generic_enumerable_type = new ConstructedType (
+                                       TypeManager.generic_ienumerable_type,
+                                       generic_args, Location);
+                               list.Add (generic_enumerable_type);
+                       }
+
+                       enumerator_type = new TypeExpression (
+                               TypeManager.ienumerator_type, Location);
+                       list.Add (enumerator_type);
+
+                       list.Add (new TypeExpression (TypeManager.idisposable_type, Location));
+
+                       generic_enumerator_type = new ConstructedType (
+                               TypeManager.generic_ienumerator_type,
+                               generic_args, Location);
+                       list.Add (generic_enumerator_type);
+
+                       iterator_type_expr = new TypeExpression (iterator_type, Location);
+
+                       container.AddIterator (this);
+
+                       Bases = list;
+                       return true;
+               }
+
+               MethodInfo FetchMethodDispose ()
+               {
+                       MemberList dispose_list;
+
+                       dispose_list = FindMembers (
+                               current_type.Type,
+                               MemberTypes.Method, BindingFlags.Public | BindingFlags.Instance,
+                               Type.FilterName, "Dispose");
+
+                       if (dispose_list.Count != 1)
+                               throw new InternalErrorException ("Cannot find Dipose() method.");
+
+                       return (MethodInfo) dispose_list [0];
+               }
+
+               protected override bool DoDefineMembers ()
+               {
+                       if (!base.DoDefineMembers ())
+                               return false;
+
+                       dispose_method = FetchMethodDispose ();
+                       if (dispose_method == null)
+                               return false;
+
+                       return true;
+               }
+
+               //
+               // Returns the new block for the method, or null on failure
+               //
+               protected override bool DefineNestedTypes ()
+               {
+                       if (CurrentType != null)
+                               current_type = new TypeExpression (CurrentType, Location);
+                       else
+                               current_type = new TypeExpression (TypeBuilder, Location);
+
+                       Define_Fields ();
+                       Define_Constructor ();
+                       Define_Current (false);
+                       Define_Current (true);
+                       Define_MoveNext ();
+                       Define_Reset ();
+                       Define_Dispose ();
+
+                       if (is_enumerable) {
+                               Define_GetEnumerator (false);
+                               Define_GetEnumerator (true);
+                       }
+
+                       Create_Block ();
+
+                       return base.DefineNestedTypes ();
+               }
+
+
+               Field pc_field;
+               Field current_field;
+               Method dispose;
+
+               public Field this_field;
+               public Field[] parameter_fields;
+
+               void Create_Block ()
+               {
+                       int first = is_static ? 0 : 1;
+
+                       ArrayList args = new ArrayList ();
+                       if (!is_static) {
+                               Type t = this_type;
+                               args.Add (new Argument (
+                                       new ThisParameterReference (t, 0, Location)));
+                       }
+
+                       args.Add (new Argument (new BoolLiteral (false)));
+
+                       for (int i = 0; i < parameters.Count; i++) {
+                               Type t = parameters.ParameterType (i);
+                               args.Add (new Argument (
+                                       new SimpleParameterReference (t, first + i, Location)));
+                       }
+
+                       Expression new_expr = new New (current_type, args, Location);
+
+                       block.AddStatement (new NoCheckReturn (new_expr, Location));
+               }
+
+               void Define_Fields ()
+               {
+                       Location loc = Location.Null;
+
+                       pc_field = new Field (
+                               this, TypeManager.system_int32_expr, Modifiers.PRIVATE, "PC",
+                               null, null, loc);
+                       AddField (pc_field);
+
+                       current_field = new Field (
+                               this, iterator_type_expr, Modifiers.PRIVATE, "current",
+                               null, null, loc);
+                       AddField (current_field);
+
+                       if (!is_static) {
+                               this_field = new Field (
+                                       this, new TypeExpression (this_type, loc),
+                                       Modifiers.PRIVATE, "this", null, null, loc);
+                               AddField (this_field);
+                       }
+
+                       parameter_fields = new Field [parameters.Count];
+                       for (int i = 0; i < parameters.Count; i++) {
+                               string fname = String.Format (
+                                       "field{0}_{1}", i, parameters.ParameterName (i));
+
+                               parameter_fields [i] = new Field (
+                                       this,
+                                       new TypeExpression (parameters.ParameterType (i), loc),
+                                       Modifiers.PRIVATE, fname, null, null, loc);
+                               AddField (parameter_fields [i]);
+                       }
+               }
+
+               void Define_Constructor ()
+               {
+                       Parameters ctor_params;
+
+                       ArrayList list = new ArrayList ();
+
+                       if (!is_static)
+                               list.Add (new Parameter (
+                                       new TypeExpression (this_type, Location),
+                                       "this", Parameter.Modifier.NONE, null));
+                       list.Add (new Parameter (
+                               TypeManager.system_boolean_expr, "initialized",
+                               Parameter.Modifier.NONE, null));
+
+                       Parameter[] old_fixed = parameters.Parameters.FixedParameters;
+                       if (old_fixed != null)
+                               list.AddRange (old_fixed);
+
+                       Parameter[] fixed_params = new Parameter [list.Count];
+                       list.CopyTo (fixed_params);
+
+                       ctor_params = new Parameters (
+                               fixed_params, parameters.Parameters.ArrayParameter,
+                               Location);
+
+                       Constructor ctor = new Constructor (
+                               this, Name, Modifiers.PUBLIC, ctor_params,
+                               new ConstructorBaseInitializer (
+                                       null, Parameters.EmptyReadOnlyParameters, Location),
+                               Location);
+                       AddConstructor (ctor);
+
+                       ToplevelBlock block = ctor.Block = new ToplevelBlock (Location);
+
+                       if (!is_static) {
+                               Type t = this_type;
+
+                               Assign assign = new Assign (
+                                       new FieldExpression (this_field),
+                                       new SimpleParameterReference (t, 1, Location),
+                                       Location);
+
+                               block.AddStatement (new StatementExpression (assign, Location));
+                       }
+
+                       int first = is_static ? 2 : 3;
+
+                       for (int i = 0; i < parameters.Count; i++) {
+                               Type t = parameters.ParameterType (i);
+
+                               Assign assign = new Assign (
+                                       new FieldExpression (parameter_fields [i]),
+                                       new SimpleParameterReference (t, first + i, Location),
+                                       Location);
+
+                               block.AddStatement (new StatementExpression (assign, Location));
+                       }
+
+                       State initial = is_enumerable ? State.Uninitialized : State.Running;
+                       block.AddStatement (new SetState (this, initial, Location));
+
+                       block.AddStatement (new If (
+                               new SimpleParameterReference (
+                                       TypeManager.bool_type, first - 1, Location),
+                               new SetState (this, State.Running, Location),
+                               Location));
+               }
+
+               Statement Create_ThrowInvalidOperation ()
+               {
+                       TypeExpr ex_type = new TypeExpression (
+                               TypeManager.invalid_operation_exception_type, Location);
+
+                       return new Throw (new New (ex_type, null, Location), Location);
+               }
+
+               Statement Create_ThrowNotSupported ()
+               {
+                       TypeExpr ex_type = new TypeExpression (
+                               TypeManager.not_supported_exception_type, Location);
+
+                       return new Throw (new New (ex_type, null, Location), Location);
+               }
+
+               void Define_Current (bool is_generic)
+               {
+                       MemberName left;
+                       Expression type;
+                       if (is_generic) {
+                               left = new MemberName (
+                                       "System.Collections.Generic.IEnumerator",
+                                       generic_args);
+                               type = iterator_type_expr;
+                       } else {
+                               left = new MemberName ("System.Collections.IEnumerator");
+                               type = TypeManager.system_object_expr;
+                       }
+
+                       MemberName name = new MemberName (left, "Current", null);
+
+                       ToplevelBlock get_block = new ToplevelBlock (Location);
+
+                       get_block.AddStatement (new If (
+                               new Binary (
+                                       Binary.Operator.LessThanOrEqual,
+                                       new FieldExpression (pc_field),
+                                       new IntLiteral ((int) State.Running), Location),
+                               Create_ThrowInvalidOperation (),
+                               new Return (
+                                       new FieldExpression (current_field), Location),
+                               Location));
+
+                       Accessor getter = new Accessor (get_block, 0, null, Location);
+
+                       Property current = new Property (
+                               this, type, 0, false, name, null, getter, null, Location);
+                       AddProperty (current);
+               }
+
+               void Define_MoveNext ()
+               {
+                       Method move_next = new Method (
+                               this, null, TypeManager.system_boolean_expr,
+                               Modifiers.PUBLIC, false, new MemberName ("MoveNext"),
+                               Parameters.EmptyReadOnlyParameters, null,
+                               Location.Null);
+                       AddMethod (move_next);
+
+                       ToplevelBlock block = move_next.Block = new ToplevelBlock (Location);
+
+                       MoveNextMethod inline = new MoveNextMethod (this, Location);
+                       block.AddStatement (inline);
+               }
+
+               void Define_GetEnumerator (bool is_generic)
+               {
+                       MemberName left;
+                       Expression type;
+                       if (is_generic) {
+                               left = new MemberName (
+                                       "System.Collections.Generic.IEnumerable",
+                                       generic_args);
+                               type = generic_enumerator_type;
+                       } else {
+                               left = new MemberName ("System.Collections.IEnumerable");
+                               type = enumerator_type;
+                       }
+
+                       MemberName name = new MemberName (left, "GetEnumerator", null);
+
+                       Method get_enumerator = new Method (
+                               this, null, type, 0, false, name,
+                               Parameters.EmptyReadOnlyParameters, null,
+                               Location.Null);
+                       AddMethod (get_enumerator);
+
+                       get_enumerator.Block = new ToplevelBlock (Location);
+
+                       Expression ce = new MemberAccess (
+                               new SimpleName ("System.Threading.Interlocked", Location),
+                               "CompareExchange", Location);
+
+                       Expression pc = new FieldExpression (pc_field);
+                       Expression before = new IntLiteral ((int) State.Running);
+                       Expression uninitialized = new IntLiteral ((int) State.Uninitialized);
+
+                       ArrayList args = new ArrayList ();
+                       args.Add (new Argument (pc, Argument.AType.Ref));
+                       args.Add (new Argument (before, Argument.AType.Expression));
+                       args.Add (new Argument (uninitialized, Argument.AType.Expression));
+
+                       get_enumerator.Block.AddStatement (new If (
+                               new Binary (
+                                       Binary.Operator.Equality,
+                                       new Invocation (ce, args, Location),
+                                       uninitialized, Location),
+                               new Return (new This (block, Location), Location),
+                               Location));
+
+                       args = new ArrayList ();
+                       if (!is_static)
+                               args.Add (new Argument (new FieldExpression (this_field)));
+
+                       args.Add (new Argument (new BoolLiteral (true)));
+
+                       for (int i = 0; i < parameters.Count; i++)
+                               args.Add (new Argument (
+                                                 new FieldExpression (parameter_fields [i])));
+
+                       Expression new_expr = new New (current_type, args, Location);
+                       get_enumerator.Block.AddStatement (new Return (new_expr, Location));
+               }
+
+               protected class SimpleParameterReference : Expression
+               {
+                       int idx;
+
+                       public SimpleParameterReference (Type type, int idx, Location loc)
+                       {
+                               this.idx = idx;
+                               this.loc = loc;
+                               this.type = type;
+                               eclass = ExprClass.Variable;
+                       }
+
+                       public override Expression DoResolve (EmitContext ec)
+                       {
+                               return this;
+                       }
+
+                       public override void Emit (EmitContext ec)
+                       {
+                               DoEmit (ec);
+                       }
+
+                       protected virtual void DoEmit (EmitContext ec)
+                       {
+                               ParameterReference.EmitLdArg (ec.ig, idx);
+                       }
+               }
+
+               protected class ThisParameterReference : SimpleParameterReference
+               {
+                       public ThisParameterReference (Type type, int idx, Location loc)
+                               : base (type, idx, loc)
+                       { }
+
+                       protected override void DoEmit (EmitContext ec)
+                       {
+                               base.DoEmit (ec);
+                               if (ec.TypeContainer is Struct)
+                                       ec.ig.Emit (OpCodes.Ldobj, type);
+                       }
+               }
+
+               protected class FieldExpression : Expression
+               {
+                       Field field;
+
+                       public FieldExpression (Field field)
+                       {
+                               this.field = field;
+                       }
+
+                       public override Expression DoResolve (EmitContext ec)
+                       {
+                               FieldExpr fexpr = new FieldExpr (field.FieldBuilder, loc);
+                               fexpr.InstanceExpression = ec.GetThis (loc);
+                               return fexpr.Resolve (ec);
+                       }
+
+                       public override void Emit (EmitContext ec)
+                       {
+                               throw new InvalidOperationException ();
+                       }
+               }
+
+               protected class MoveNextMethod : Statement {
+                       Iterator iterator;
+
+                       public MoveNextMethod (Iterator iterator, Location loc)
+                       {
+                               this.loc = loc;
+                               this.iterator = iterator;
+                       }
+
+                       public override bool Resolve (EmitContext ec)
+                       {
+                               ec.CurrentBranching.CurrentUsageVector.Return ();
+                               return true;
+                       }
+
+                       protected override void DoEmit (EmitContext ec)
+                       {
+                               int code_flags = Modifiers.METHOD_YIELDS;
+                               if (iterator.is_static)
+                                       code_flags |= Modifiers.STATIC;
+
+                               EmitContext new_ec = new EmitContext (
+                                       iterator.container, loc, ec.ig,
+                                       TypeManager.int32_type, code_flags);
+
+                               new_ec.CurrentIterator = iterator;
+
+                               iterator.EmitMoveNext (new_ec);
+                       }
+               }
+
+               protected class DisposeMethod : Statement {
+                       Iterator iterator;
+
+                       public DisposeMethod (Iterator iterator, Location loc)
+                       {
+                               this.loc = loc;
+                               this.iterator = iterator;
+                       }
+
+                       public override bool Resolve (EmitContext ec)
+                       {
+                               return true;
+                       }
+
+                       protected override void DoEmit (EmitContext ec)
+                       {
+                               iterator.EmitDispose (ec);
+                       }
+               }
+
+               protected class StatementList : Statement {
+                       ArrayList statements;
+
+                       public StatementList (Location loc)
+                       {
+                               this.loc = loc;
+                               statements = new ArrayList ();
+                       }
+
+                       public void Add (Statement statement)
+                       {
+                               statements.Add (statement);
+                       }
+
+                       public override bool Resolve (EmitContext ec)
+                       {
+                               foreach (Statement stmt in statements) {
+                                       if (!stmt.Resolve (ec))
+                                               return false;
+                               }
+
+                               return true;
+                       }
+
+                       protected override void DoEmit (EmitContext ec)
+                       {
+                               foreach (Statement stmt in statements)
+                                       stmt.Emit (ec);
+                       }
+               }
+
+               protected class SetState : Statement
+               {
+                       Iterator iterator;
+                       State state;
+
+                       public SetState (Iterator iterator, State state, Location loc)
+                       {
+                               this.iterator = iterator;
+                               this.state = state;
+                               this.loc = loc;
+                       }
+
+                       public override bool Resolve (EmitContext ec)
+                       {
+                               return true;
+                       }
+
+                       protected override void DoEmit (EmitContext ec)
+                       {
+                               ec.ig.Emit (OpCodes.Ldarg_0);
+                               IntConstant.EmitInt (ec.ig, (int) state);
+                               ec.ig.Emit (OpCodes.Stfld, iterator.pc_field.FieldBuilder);
+                       }
+               }
+
+               void Define_Reset ()
+               {
+                       Method reset = new Method (
+                               this, null, TypeManager.system_void_expr, Modifiers.PUBLIC,
+                               false, new MemberName ("Reset"),
+                               Parameters.EmptyReadOnlyParameters, null, Location);
+                       AddMethod (reset);
+
+                       reset.Block = new ToplevelBlock (Location);
+                       reset.Block.AddStatement (Create_ThrowNotSupported ());
+               }
+
+               void Define_Dispose ()
+               {
+                       dispose = new Method (
+                               this, null, TypeManager.system_void_expr, Modifiers.PUBLIC,
+                               false, new MemberName ("Dispose"),
+                               Parameters.EmptyReadOnlyParameters, null, Location);
+                       AddMethod (dispose);
+
+                       dispose.Block = new ToplevelBlock (Location);
+                       dispose.Block.AddStatement (new DisposeMethod (this, Location));
+               }
+
+               public ToplevelBlock Block {
+                       get { return block; }
+               }
+
+               public Type IteratorType {
+                       get { return iterator_type; }
+               }
+
+               //
+               // This return statement tricks return into not flagging an error for being
+               // used in a Yields method
+               //
+               class NoCheckReturn : Return {
+                       public NoCheckReturn (Expression expr, Location loc) : base (expr, loc)
+                       {
+                       }
+
+                       public override bool Resolve (EmitContext ec)
+                       {
+                               ec.InIterator = false;
+                               bool ret_val = base.Resolve (ec);
+                               ec.InIterator = true;
+
+                               return ret_val;
+                       }
+               }
+
+               bool CheckType (Type t)
+               {
+                       if (t == TypeManager.ienumerable_type) {
+                               iterator_type = TypeManager.object_type;
+                               is_enumerable = true;
+                               return true;
+                       } else if (t == TypeManager.ienumerator_type) {
+                               iterator_type = TypeManager.object_type;
+                               is_enumerable = false;
+                               return true;
+                       }
+
+                       if (!t.IsGenericInstance)
+                               return false;
+
+                       Type[] args = TypeManager.GetTypeArguments (t);
+                       if (args.Length != 1)
+                               return false;
+
+                       Type gt = t.GetGenericTypeDefinition ();
+                       if (gt == TypeManager.generic_ienumerable_type) {
+                               iterator_type = args [0];
+                               is_enumerable = true;
+                               return true;
+                       } else if (gt == TypeManager.generic_ienumerator_type) {
+                               iterator_type = args [0];
+                               is_enumerable = false;
+                               return true;
+                       }
+
+                       return false;
+               }
+       }
+}
+
diff --git a/mcs/bmcs/literal.cs b/mcs/bmcs/literal.cs
new file mode 100644 (file)
index 0000000..0a97d50
--- /dev/null
@@ -0,0 +1,250 @@
+//
+// literal.cs: Literal representation for the IL tree.
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+//
+// Notice that during parsing we create objects of type Literal, but the
+// types are not loaded (thats why the Resolve method has to assign the
+// type at that point).
+//
+// Literals differ from the constants in that we know we encountered them
+// as a literal in the source code (and some extra rules apply there) and
+// they have to be resolved (since during parsing we have not loaded the
+// types yet) while constants are created only after types have been loaded
+// and are fully resolved when born.
+//
+
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+
+//
+// I put System.Null just so we do not have to special case it on 
+// TypeManager.CSharpName
+//
+namespace System {
+       //
+       // Represents the Null Type, just used as a placeholder for the type in NullLiteral
+       //
+       public class Null {
+       }
+}
+       
+namespace Mono.CSharp {
+
+       //
+       // The NullType just exists to compare type equality, and for
+       // expressions that might have the `null type'
+       //
+       public class NullType {
+       }
+
+       //
+       // The null Literal constant
+       //
+       public class NullLiteral : Constant {
+               public static readonly NullLiteral Null;
+
+               static NullLiteral ()
+               {
+                       Null = new NullLiteral ();
+               }
+                       
+               public NullLiteral ()
+               {
+                       eclass = ExprClass.Value;
+               }
+               
+               override public string AsString ()
+               {
+                       return "null";
+               }
+
+               public override object GetValue ()
+               {
+                       return null;
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.null_type;
+                       return this;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ec.ig.Emit (OpCodes.Ldnull);
+               }
+               
+               public override bool IsNegative {
+                       get {
+                               return false;
+                       }
+               }
+
+               public override bool IsZeroInteger {
+                       get { return true; }
+               }
+       }
+
+       //
+       // A null literal in a pointer context
+       //
+       public class NullPointer : NullLiteral {
+               public new static readonly NullLiteral Null;
+
+               static NullPointer ()
+               {
+                       Null = new NullPointer ();
+               }
+               
+               private NullPointer ()
+               {
+                       type = TypeManager.object_type;
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                               
+                       ig.Emit (OpCodes.Ldc_I4_0);
+                       ig.Emit (OpCodes.Conv_U);
+               }
+       }
+
+       public class BoolLiteral : BoolConstant {
+               public BoolLiteral (bool val) : base (val)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.bool_type;
+                       return this;
+               }
+       }
+
+       public class CharLiteral : CharConstant {
+               public CharLiteral (char c) : base (c)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.char_type;
+                       return this;
+               }
+       }
+
+       public class IntLiteral : IntConstant {
+               public static IntLiteral One, Zero;
+               
+               static IntLiteral ()
+               {
+                       Zero = new IntLiteral (0);
+                       One = new IntLiteral (1);
+               }
+               
+               public IntLiteral (int l) : base (l)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.int32_type;
+                       return this;
+               }
+       }
+
+       public class UIntLiteral : UIntConstant {
+               public UIntLiteral (uint l) : base (l)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.uint32_type;
+                       return this;
+               }
+       }
+       
+       public class LongLiteral : LongConstant {
+               public LongLiteral (long l) : base (l)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.int64_type;
+
+                       return this;
+               }
+       }
+
+       public class ULongLiteral : ULongConstant {
+               public ULongLiteral (ulong l) : base (l)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.uint64_type;
+                       return this;
+               }
+       }
+       
+       public class FloatLiteral : FloatConstant {
+               
+               public FloatLiteral (float f) : base (f)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.float_type;
+                       return this;
+               }
+       }
+
+       public class DoubleLiteral : DoubleConstant {
+               public DoubleLiteral (double d) : base (d)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.double_type;
+
+                       return this;
+               }
+       }
+
+       public class DecimalLiteral : DecimalConstant {
+               public DecimalLiteral (decimal d) : base (d)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.decimal_type;
+                       return this;
+               }
+       }
+
+       public class StringLiteral : StringConstant {
+               public StringLiteral (string s) : base (s)
+               {
+               }
+
+               public override Expression DoResolve (EmitContext ec)
+               {
+                       type = TypeManager.string_type;
+
+                       return this;
+               }
+       }
+}
diff --git a/mcs/bmcs/location.cs b/mcs/bmcs/location.cs
new file mode 100644 (file)
index 0000000..a318885
--- /dev/null
@@ -0,0 +1,234 @@
+//
+// location.cs: Keeps track of the location of source code entity
+//
+// Author:
+//   Miguel de Icaza
+//
+// (C) 2001 Ximian, Inc.
+//
+
+using System;
+using System.IO;
+using System.Collections;
+using Mono.CompilerServices.SymbolWriter;
+
+namespace Mono.CSharp {
+       /// <summary>
+       ///   This is one single source file.
+       /// </summary>
+       /// <remarks>
+       ///   This is intentionally a class and not a struct since we need
+       ///   to pass this by reference.
+       /// </remarks>
+       public sealed class SourceFile : ISourceFile {
+               public readonly string Name;
+               public readonly string Path;
+               public readonly int Index;
+               public SourceFileEntry SourceFileEntry;
+               public bool HasLineDirective;
+
+               public SourceFile (string name, string path, int index)
+               {
+                       this.Index = index;
+                       this.Name = name;
+                       this.Path = path;
+               }
+
+               SourceFileEntry ISourceFile.Entry {
+                       get { return SourceFileEntry; }
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("SourceFile ({0}:{1}:{2}:{3})",
+                                             Name, Path, Index, SourceFileEntry);
+               }
+       }
+
+       /// <summary>
+       ///   Keeps track of the location in the program
+       /// </summary>
+       ///
+       /// <remarks>
+       ///   This uses a compact representation and a couple of auxiliary
+       ///   structures to keep track of tokens to (file,line) mappings.
+       ///
+       ///   We could probably also keep track of columns by storing those
+       ///   in 8 bits (and say, map anything after char 255 to be `255+').
+       /// </remarks>
+       public struct Location {
+               public int token; 
+
+               static ArrayList source_list;
+               static Hashtable source_files;
+               static int source_bits;
+               static int source_mask;
+               static int source_count;
+               static int current_source;
+
+               public readonly static Location Null;
+               
+               static Location ()
+               {
+                       source_files = new Hashtable ();
+                       source_list = new ArrayList ();
+                       current_source = 0;
+                       Null.token = 0;
+               }
+
+               // <summary>
+               //   This must be called before parsing/tokenizing any files.
+               // </summary>
+               static public void AddFile (string name)
+               {
+                       string path = Path.GetFullPath (name);
+
+                       if (source_files.Contains (path)){
+                               Report.Warning (2002, name, "Source file '{0}' specified multiple times");
+                               return;
+                       }
+
+                       source_files.Add (path, ++source_count);
+                       source_list.Add (new SourceFile (name, path, source_count));
+               }
+
+               static public SourceFile[] SourceFiles {
+                       get {
+                               SourceFile[] retval = new SourceFile [source_list.Count];
+                               source_list.CopyTo (retval, 0);
+                               return retval;
+                       }
+               }
+
+               static int log2 (int number)
+               {
+                       int bits = 0;
+                       while (number > 0) {
+                               bits++;
+                               number /= 2;
+                       }
+
+                       return bits;
+               }
+
+               // <summary>
+               //   After adding all source files we want to compile with AddFile(), this method
+               //   must be called to `reserve' an appropriate number of bits in the token for the
+               //   source file.  We reserve some extra space for files we encounter via #line
+               //   directives while parsing.
+               // </summary>
+               static public void Initialize ()
+               {
+                       source_bits = log2 (source_list.Count) + 2;
+                       source_mask = (1 << source_bits) - 1;
+               }
+
+               // <remarks>
+               //   This is used when we encounter a #line preprocessing directive.
+               // </remarks>
+               static public SourceFile LookupFile (string name)
+               {
+                       string path = name == "" ? "" : Path.GetFullPath (name);
+
+                       if (!source_files.Contains (path)) {
+                               if (source_count >= (1 << source_bits))
+                                       return new SourceFile (name, path, 0);
+
+                               source_files.Add (path, ++source_count);
+                               SourceFile retval = new SourceFile (name, path, source_count);
+                               source_list.Add (retval);
+                               return retval;
+                       }
+
+                       int index = (int) source_files [path];
+                       return (SourceFile) source_list [index - 1];
+               }
+
+/*
+               static public void Push (SourceFile file)
+               {
+                       current_source = file.Index;
+               }
+*/             
+
+               // <remarks>
+               //   If we're compiling with debugging support, this is called between parsing
+               //   and code generation to register all the source files with the
+               //   symbol writer.
+               // </remarks>
+               static public void DefineSymbolDocuments (SymbolWriter symwriter)
+               {
+                       foreach (SourceFile file in source_list) {
+                               file.SourceFileEntry = symwriter.DefineDocument (file.Path);
+                       }
+               }
+               
+               public Location (int row)
+               {
+                       if (row < 0)
+                               token = 0;
+                       else
+                               token = current_source + (row << source_bits);
+               }
+
+               public override string ToString ()
+               {
+                       return Name + ": (" + Row + ")";
+               }
+               
+               /// <summary>
+               ///   Whether the Location is Null
+               /// </summary>
+               static public bool IsNull (Location l)
+               {
+                       return l.token == 0;
+               }
+
+               public string Name {
+                       get {
+                               int index = token & source_mask;
+                               if ((token == 0) || (index == 0))
+                                       return "Internal";
+
+                               SourceFile file = (SourceFile) source_list [index - 1];
+                               return file.Name;
+                       }
+               }
+
+               public int Row {
+                       get {
+                               if (token == 0)
+                                       return 1;
+
+                               return token >> source_bits;
+                       }
+               }
+
+               public int File {
+                       get {
+                               return token & source_mask;
+                       }
+               }
+
+               // The ISymbolDocumentWriter interface is used by the symbol writer to
+               // describe a single source file - for each source file there's exactly
+               // one corresponding ISymbolDocumentWriter instance.
+               //
+               // This class has an internal hash table mapping source document names
+               // to such ISymbolDocumentWriter instances - so there's exactly one
+               // instance per document.
+               //
+               // This property returns the ISymbolDocumentWriter instance which belongs
+               // to the location's source file.
+               //
+               // If we don't have a symbol writer, this property is always null.
+               public SourceFile SourceFile {
+                       get {
+                               int index = token & source_mask;
+                               if (index == 0)
+                                       return null;
+                               return (SourceFile) source_list [index - 1];
+                       }
+               }
+       }
+}
diff --git a/mcs/bmcs/mb-parser.cs b/mcs/bmcs/mb-parser.cs
new file mode 100644 (file)
index 0000000..514ce47
--- /dev/null
@@ -0,0 +1,7416 @@
+// created by jay 0.7 (c) 1998 Axel.Schreiner@informatik.uni-osnabrueck.de
+
+#line 2 "mb-parser.jay"
+//
+// Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
+//
+// Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+//         Anirban Bhattacharjee (banirban@novell.com)
+//          Jambunathan K (kjambunathan@novell.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira
+// Copyright (C) 2003, 2004 Novell
+//
+//
+
+namespace Mono.CSharp
+{
+       using System.Text;
+       using System;
+       using System.Reflection;
+       using System.Collections;
+       using Mono.CSharp;
+
+       /// <summary>
+       ///    The MonoBASIC Parser
+       /// </summary>
+//     [DefaultParser]
+//     public class Parser : GenericParser
+//     {
+       
+
+//             /// <summary>
+//             ///   Current block is used to add statements as we find
+//             ///   them.  
+//             /// </summary>
+//             Block      current_block;
+               
+//             /// <summary>
+//             ///   Tmp block is used to store block endings in if/select's
+//             /// </summary>
+//             Block      tmp_block;           
+
+//             /// <summary>
+//             ///   Tmp block is used to store tmp copies of expressions
+//             /// </summary>
+//             Expression      tmp_expr;       
+               
+//             /// <summary>
+//             ///   Tmp catch is used to store catch clauses in try..catch..finally
+//             /// </summary>
+//             ArrayList      tmp_catch_clauses;                       
+               
+//             /// <summary>
+//             ///   Current interface is used by the various declaration
+//             ///   productions in the interface declaration to "add"
+//             ///   the interfaces as we find them.
+//             /// </summary>
+//             Interface  current_interface;
+
+//             /// <summary>
+//             ///   This is used by the unary_expression code to resolve
+//             ///   a name against a parameter.  
+//             /// </summary>
+//             Parameters current_local_parameters;
+               
+//             /// <summary>
+//             ///   This are used when parsing parameters in property
+//             ///   declarations.
+//             /// </summary>          
+//             Parameters set_parameters;
+//             Parameters get_parameters;
+               
+//             /// <summary>
+//             ///   This is used by the sub_header parser to store modifiers
+//             ///   to be passed to sub/constructor  
+//             /// </summary>
+//             int current_modifiers;          
+                       
+//             /// <summary>
+//             ///   This is used by the sub_header parser to store attributes
+//             ///   to be passed to sub/constructor  
+//             /// </summary>
+//             Attributes current_attributes;                          
+
+//             /// <summary>
+//             ///   Using during property parsing to describe the implicit
+//             ///   value parameter that is passed to the "set" accessor
+//             ///   method
+//             /// </summary>
+//             string get_implicit_value_parameter_name;
+               
+//             // <summary>
+//             //   Using during property parsing to describe the implicit
+//             //   value parameter that is passed to the "set" and "get"accesor
+//             //   methods (properties and indexers).
+//             // </summary>
+//             Expression get_implicit_value_parameter_type;
+               
+//             /// <summary>
+//             ///   Using during property parsing to describe the implicit
+//             ///   value parameter that is passed to the "set" accessor
+//             ///   method
+//             /// </summary>
+//             string set_implicit_value_parameter_name;
+               
+//             // <summary>
+//             //   Using during property parsing to describe the implicit
+//             //   value parameter that is passed to the "set" and "get"accesor
+//             //   methods (properties and indexers).
+//             // </summary>
+//             Expression set_implicit_value_parameter_type;           
+               
+//             Location member_location;
+               
+//             // An out-of-band stack.
+//             //
+//             Stack oob_stack;
+               
+//             ArrayList current_rank_specifiers;
+
+//             DoOptions do_type;
+//             //
+//             // Switch stack.
+//             //
+//             Stack switch_stack;
+               
+//             // Expression stack for nested ifs
+//             Stack expr_stack; 
+               
+//             Stack tmp_blocks;
+//             Stack statement_stack;
+
+//             // A stack for With expressions.
+//             //
+//             Stack with_stack;
+       
+               
+//             static public bool InitialOptionExplicit = false;
+//             static public bool InitialOptionStrict = false;
+//             static public bool InitialOptionCompareBinary = true;
+//             static public ArrayList ImportsList = null;
+
+//             bool OptionExplicit;
+//             bool OptionStrict;
+//             bool OptionCompareBinary;
+
+//             static public bool UseExtendedSyntax; // for ".mbs" files
+
+//             bool implicit_modifiers;
+               
+//             public override string[] extensions()
+//             {
+//                     string [] list = { ".vb", ".mbs" };
+//                     return list;
+//             }
+
+
+       /// <summary>
+       ///    The C# Parser
+       /// </summary>
+       public class CSharpParser {
+               NamespaceEntry  current_namespace;
+               TypeContainer   current_container;
+               TypeContainer   current_class;
+       
+               IIteratorContainer iterator_container;
+
+               /// <summary>
+               ///   Current block is used to add statements as we find
+               ///   them.  
+               /// </summary>
+               Block      current_block, top_current_block;
+
+               /// <summary>
+               ///   This is used by the unary_expression code to resolve
+               ///   a name against a parameter.  
+               /// </summary>
+               Parameters current_local_parameters;
+
+               /// <summary>
+               ///   Using during property parsing to describe the implicit
+               ///   value parameter that is passed to the "set" and "get"accesor
+               ///   methods (properties and indexers).
+               /// </summary>
+               Expression implicit_value_parameter_type;
+               Parameters indexer_parameters;
+
+               /// <summary>
+               ///   Used to determine if we are parsing the get/set pair
+               ///   of an indexer or a property
+               /// </summmary>
+               bool  parsing_indexer;
+
+               ///
+               /// An out-of-band stack.
+               ///
+               Stack oob_stack;
+
+               ///
+               /// Switch stack.
+               ///
+               Stack switch_stack;
+
+               static public int yacc_verbose_flag;
+
+               // Name of the file we are parsing
+               public string name;
+
+               ///
+               /// The current file.
+               ///
+               SourceFile file;
+               
+               ///   This is used by the sub_header parser to store modifiers
+               ///   to be passed to sub/constructor  
+               int current_modifiers;          
+                       
+               ///   This is used by the sub_header parser to store attributes
+               ///   to be passed to sub/constructor  
+               Attributes current_attributes;                          
+
+               ///   This is used by the attributes parser to syntactically
+               ///   validate the attribute rules  
+               bool allow_global_attribs = true;
+
+               bool expecting_global_attribs = false;
+               bool expecting_local_attribs = false;
+
+               bool local_attrib_section_added = false;
+
+               ///FIXME
+               ArrayList current_rank_specifiers;
+
+               /// <summary>
+               ///   Using during property parsing to describe the implicit
+               ///   value parameter that is passed to the "set" accessor
+               ///   method
+               /// </summary>
+               string get_implicit_value_parameter_name;
+               
+               // <summary>
+               //   Using during property parsing to describe the implicit
+               //   value parameter that is passed to the "set" and "get"accesor
+               //   methods (properties and indexers).
+               // </summary>
+               Expression get_implicit_value_parameter_type;
+               
+               /// <summary>
+               ///   Using during property parsing to describe the implicit
+               ///   value parameter that is passed to the "set" accessor
+               ///   method
+               /// </summary>
+               string set_implicit_value_parameter_name;
+               
+               // <summary>
+               //   Using during property parsing to describe the implicit
+               //   value parameter that is passed to the "set" and "get"accesor
+               //   methods (properties and indexers).
+               // </summary>
+               Expression set_implicit_value_parameter_type;           
+
+               /// <summary>
+               ///   This are used when parsing parameters in property
+               ///   declarations.
+               /// </summary>          
+               Parameters set_parameters;
+               Parameters get_parameters;
+
+//             static public ArrayList ImportsList = null;
+
+               bool implicit_modifiers;
+
+
+               /// <summary>
+               ///   This is used as a helper class for handling of
+               ///   pre-processor statements.
+               /// </summary>          
+
+               // FIXME: This class MBASException is actually a kludge 
+               // It can be done away with a more elegant replacement.
+
+               public class MBASException : ApplicationException
+               {
+                       public int code;
+                       public Location loc;
+
+                       public MBASException(int code, Location loc, string text) : base(text)
+                       {
+                               this.code = code;
+                               this.loc = loc;
+                       }
+               }
+
+
+
+               public class IfElseStateMachine {
+                       
+                       public enum State {
+                               START,
+                               IF_SEEN,
+                               ELSEIF_SEEN,
+                               ELSE_SEEN,
+                               ENDIF_SEEN,
+                               MAX
+                       }
+               
+                       public enum Token {
+                               START,
+                               IF,
+                               ELSEIF,
+                               ELSE,
+                               ENDIF,
+                               EOF,
+                               MAX
+                       }
+
+                       State state;
+                       Stack stateStack;
+
+                       public static Hashtable errStrings = new Hashtable();
+
+                       int err=0;
+                       static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
+               
+                       static IfElseStateMachine()
+                       {
+                               // FIXME: Fix both the error nos and the error strings. 
+                               // Currently the error numbers and the error strings are 
+                               // just placeholders for getting the state-machine going.
+
+                               errStrings.Add(0, "");
+                               errStrings.Add(30012, "#If must end with a matching #End If");
+                               errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
+                               errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
+                               errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
+                               errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
+
+                               errTable[(int)State.START, (int)Token.IF] = 0;
+                               errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
+                               errTable[(int)State.START, (int)Token.ELSE] = 30028;
+                               errTable[(int)State.START, (int)Token.ENDIF] = 30013;
+                               errTable[(int)State.START, (int)Token.EOF] = 0;
+
+                               errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
+
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
+
+                               errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
+
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
+                       }
+
+                       public IfElseStateMachine()
+                       {
+                               state = State.START;
+
+                               stateStack = new Stack();
+                               stateStack.Push(state);
+                       }
+
+                       // The parameter here need not be qualified with IfElseStateMachine
+                       // But it hits a bug in mcs. So temporarily scoping it so that builds
+                       // are not broken.
+
+                       public void HandleToken(IfElseStateMachine.Token tok)
+                       {       
+                               err = (int) errTable[(int)state, (int)tok];
+
+                               if(err != 0)
+                                       throw new ApplicationException("Unexpected pre-processor directive #"+tok); 
+                               
+                               if(tok == Token.IF) {
+                                       stateStack.Push(state);
+                                       state = (State) tok;
+                               }
+                               else if(tok == Token.ENDIF) {
+                                       state = (State)stateStack.Pop();
+                               }
+                               else
+                                       state = (State)tok;
+                       }
+
+                       public int Error {
+                               get {
+                                       return err;
+                               }
+                       }
+
+                       public string ErrString {
+                               get {
+                                       return (string) errStrings[err];
+                               }
+                       }
+               }
+
+               
+               public class TokenizerController {
+                       
+                       struct State
+                       {
+                               public bool CanAcceptTokens;
+                               public bool CanSelectBlock;
+
+                       }
+
+                       State currentState;
+                       Stack stateStack;
+                       Tokenizer lexer;
+
+                       public TokenizerController(Tokenizer lexer)
+                       {
+                               this.lexer = lexer;
+                               stateStack = new Stack();
+
+                               currentState.CanAcceptTokens = true;
+                               currentState.CanSelectBlock = true;
+
+                               stateStack.Push(currentState);
+                       }
+
+                       State parentState {
+                               get {
+                                       return (State)stateStack.Peek();
+                               }
+                       }
+
+                       public bool IsAcceptingTokens {
+                               get {
+                                       return currentState.CanAcceptTokens;
+                               }
+                       }
+
+                       public void PositionCursorAtNextPreProcessorDirective()
+                       {
+                               lexer.PositionCursorAtNextPreProcessorDirective();
+                       }
+
+                       public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
+                       {
+                               if(tok == IfElseStateMachine.Token.ENDIF) {
+                                       currentState = (State)stateStack.Pop();
+
+                                       if(currentState.CanAcceptTokens)
+                                               return;
+                                       else {
+                                               PositionCursorAtNextPreProcessorDirective();
+                                               return;
+                                       }
+                               }
+                               
+                               if(tok == IfElseStateMachine.Token.IF) {
+                                       stateStack.Push(currentState);
+                                       
+                                       currentState.CanAcceptTokens = parentState.CanAcceptTokens;
+                                       currentState.CanSelectBlock = true;
+                               }
+                       
+                               if(parentState.CanAcceptTokens && 
+                                  currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
+                                   
+                                       currentState.CanAcceptTokens = true;
+                                       currentState.CanSelectBlock = false; 
+                                       return;
+                               }
+                               else {
+                                       currentState.CanAcceptTokens = false;
+                                       PositionCursorAtNextPreProcessorDirective();
+                                       return;
+                               }
+                       }
+               }
+
+               bool in_external_source = false;
+               int in_marked_region = 0;
+
+               TokenizerController tokenizerController;
+               IfElseStateMachine ifElseStateMachine;
+
+
+
+#line default
+
+  /** error output stream.
+      It should be changeable.
+    */
+  public System.IO.TextWriter ErrorOutput = System.Console.Out;
+
+  /** simplified error message.
+      @see <a href="#yyerror(java.lang.String, java.lang.String[])">yyerror</a>
+    */
+  public void yyerror (string message) {
+    yyerror(message, null);
+  }
+
+  /** (syntax) error message.
+      Can be overwritten to control message format.
+      @param message text to be displayed.
+      @param expected vector of acceptable tokens, if available.
+    */
+  public void yyerror (string message, string[] expected) {
+    if ((yacc_verbose_flag > 0) && (expected != null) && (expected.Length  > 0)) {
+      ErrorOutput.Write (message+", expecting");
+      for (int n = 0; n < expected.Length; ++ n)
+        ErrorOutput.Write (" "+expected[n]);
+        ErrorOutput.WriteLine ();
+    } else
+      ErrorOutput.WriteLine (message);
+  }
+
+  /** debugging support, requires the package jay.yydebug.
+      Set to null to suppress debugging messages.
+    */
+  internal yydebug.yyDebug debug;
+
+  protected static  int yyFinal = 2;
+  public static  string [] yyRule = {
+    "$accept : compilation_unit",
+    "end_of_stmt : logical_end_of_line",
+    "end_of_stmt : COLON",
+    "logical_end_of_line : EOL",
+    "logical_end_of_line : logical_end_of_line pp_directive",
+    "compilation_unit : logical_end_of_line opt_option_directives opt_imports_directives declarations EOF",
+    "compilation_unit : logical_end_of_line opt_option_directives opt_imports_directives opt_attributes EOF",
+    "opt_option_directives :",
+    "opt_option_directives : option_directives",
+    "option_directives : option_directive",
+    "option_directives : option_directives option_directive",
+    "option_directive : option_explicit_directive",
+    "option_directive : option_strict_directive",
+    "option_directive : option_compare_directive",
+    "on_off :",
+    "on_off : ON",
+    "on_off : OFF",
+    "text_or_binary : BINARY",
+    "text_or_binary : TEXT",
+    "option_explicit_directive : OPTION EXPLICIT on_off logical_end_of_line",
+    "option_strict_directive : OPTION STRICT on_off logical_end_of_line",
+    "option_compare_directive : OPTION COMPARE text_or_binary logical_end_of_line",
+    "opt_declarations :",
+    "opt_declarations : declarations",
+    "declarations : declaration",
+    "declarations : declarations declaration",
+    "$$1 :",
+    "declaration : declaration_qualifiers $$1 namespace_declaration",
+    "$$2 :",
+    "declaration : declaration_qualifiers $$2 type_spec_declaration",
+    "identifier : IDENTIFIER",
+    "identifier : BINARY",
+    "identifier : TEXT",
+    "identifier : COMPARE",
+    "identifier : EXPLICIT",
+    "identifier : OFF",
+    "type_character : PERCENT",
+    "type_character : LONGTYPECHAR",
+    "type_character : AT_SIGN",
+    "type_character : SINGLETYPECHAR",
+    "type_character : NUMBER_SIGN",
+    "type_character : DOLAR_SIGN",
+    "opt_type_character :",
+    "opt_type_character : type_character",
+    "qualified_identifier : identifier",
+    "qualified_identifier : qualified_identifier DOT identifier",
+    "opt_imports_directives :",
+    "opt_imports_directives : imports_directives",
+    "imports_directives : imports_directive",
+    "imports_directives : imports_directives imports_directive",
+    "imports_directive : IMPORTS imports_terms logical_end_of_line",
+    "imports_terms : imports_term",
+    "imports_terms : imports_terms COMMA imports_term",
+    "imports_term : namespace_or_type_name",
+    "imports_term : identifier ASSIGN namespace_or_type_name",
+    "opt_params :",
+    "opt_params : OPEN_PARENS CLOSE_PARENS",
+    "opt_params : OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS",
+    "opt_attributes :",
+    "opt_attributes : attribute_sections",
+    "attribute_sections : attribute_section",
+    "$$3 :",
+    "attribute_sections : attribute_sections $$3 attribute_section",
+    "attribute_section : OP_LT attribute_list OP_GT opt_end_of_stmt",
+    "opt_end_of_stmt :",
+    "opt_end_of_stmt : end_of_stmt",
+    "attribute_list : attribute",
+    "attribute_list : attribute_list COMMA attribute",
+    "$$4 :",
+    "attribute : namespace_or_type_name $$4 opt_attribute_arguments",
+    "$$5 :",
+    "$$6 :",
+    "attribute : attribute_target_specifier $$5 COLON namespace_or_type_name $$6 opt_attribute_arguments",
+    "attribute_target_specifier : ASSEMBLY",
+    "attribute_target_specifier : MODULE",
+    "attribute_target_specifier : namespace_or_type_name",
+    "opt_attribute_arguments :",
+    "opt_attribute_arguments : OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS",
+    "opt_attribute_arguments_list :",
+    "opt_attribute_arguments_list : attribute_arguments_list",
+    "attribute_arguments_list : positional_argument_list",
+    "attribute_arguments_list : positional_argument_list COMMA named_argument_list",
+    "attribute_arguments_list : named_argument_list",
+    "positional_argument_list : constant_expression",
+    "positional_argument_list : positional_argument_list COMMA constant_expression",
+    "named_argument_list : named_argument",
+    "named_argument_list : named_argument_list COMMA named_argument",
+    "named_argument : identifier ATTR_ASSIGN constant_expression",
+    "$$7 :",
+    "namespace_declaration : NAMESPACE qualified_identifier logical_end_of_line $$7 opt_declarations END NAMESPACE logical_end_of_line",
+    "declaration_qualifiers : opt_attributes opt_modifiers",
+    "type_spec_declaration : class_declaration",
+    "type_spec_declaration : module_declaration",
+    "type_spec_declaration : interface_declaration",
+    "type_spec_declaration : delegate_declaration",
+    "type_spec_declaration : struct_declaration",
+    "type_spec_declaration : enum_declaration",
+    "$$8 :",
+    "$$9 :",
+    "class_declaration : CLASS identifier logical_end_of_line $$8 opt_inherits opt_implements $$9 opt_class_member_declarations END CLASS logical_end_of_line",
+    "opt_inherits :",
+    "opt_inherits : INHERITS type_list logical_end_of_line",
+    "opt_implements :",
+    "opt_implements : IMPLEMENTS type_list logical_end_of_line",
+    "opt_modifiers :",
+    "opt_modifiers : modifiers",
+    "modifiers : modifier",
+    "modifiers : modifiers modifier",
+    "modifier : PUBLIC",
+    "modifier : PROTECTED",
+    "modifier : PRIVATE",
+    "modifier : SHARED",
+    "modifier : FRIEND",
+    "modifier : NOTINHERITABLE",
+    "modifier : OVERRIDABLE",
+    "modifier : NOTOVERRIDABLE",
+    "modifier : OVERRIDES",
+    "modifier : OVERLOADS",
+    "modifier : SHADOWS",
+    "modifier : MUSTINHERIT",
+    "modifier : READONLY",
+    "modifier : DEFAULT",
+    "modifier : WRITEONLY",
+    "$$10 :",
+    "module_declaration : MODULE identifier logical_end_of_line $$10 opt_module_member_declarations END MODULE logical_end_of_line",
+    "opt_module_member_declarations :",
+    "opt_module_member_declarations : module_member_declarations",
+    "module_member_declarations : module_member_declaration",
+    "module_member_declarations : module_member_declarations module_member_declaration",
+    "$$11 :",
+    "module_member_declaration : opt_attributes opt_modifiers $$11 module_member_declarator",
+    "module_member_declarator : constructor_declaration",
+    "module_member_declarator : method_declaration",
+    "module_member_declarator : field_declaration",
+    "module_member_declarator : constant_declaration",
+    "module_member_declarator : property_declaration",
+    "module_member_declarator : event_declaration",
+    "module_member_declarator : type_spec_declaration",
+    "constant_declaration : CONST constant_declarators logical_end_of_line",
+    "opt_class_member_declarations :",
+    "opt_class_member_declarations : class_member_declarations",
+    "class_member_declarations : class_member_declaration",
+    "class_member_declarations : class_member_declarations class_member_declaration",
+    "class_member_declaration : opt_attributes opt_modifiers class_member_declarator",
+    "class_member_declarator : field_declaration",
+    "class_member_declarator : constant_declaration",
+    "class_member_declarator : method_declaration",
+    "class_member_declarator : constructor_declaration",
+    "class_member_declarator : property_declaration",
+    "class_member_declarator : event_declaration",
+    "class_member_declarator : type_spec_declaration",
+    "method_declaration : sub_declaration",
+    "method_declaration : func_declaration",
+    "$$12 :",
+    "sub_declaration : SUB identifier opt_params $$12 opt_evt_handler opt_implement_clause logical_end_of_line begin_block opt_statement_list end_block END SUB logical_end_of_line",
+    "$$13 :",
+    "$$14 :",
+    "func_declaration : FUNCTION identifier opt_type_character opt_params opt_type_with_ranks $$13 opt_implement_clause logical_end_of_line begin_block $$14 opt_statement_list end_block END FUNCTION logical_end_of_line",
+    "$$15 :",
+    "$$16 :",
+    "struct_declaration : STRUCTURE identifier logical_end_of_line opt_implement_clause $$15 opt_struct_member_declarations $$16 END STRUCTURE logical_end_of_line",
+    "opt_logical_end_of_line :",
+    "opt_logical_end_of_line : logical_end_of_line",
+    "opt_struct_member_declarations :",
+    "opt_struct_member_declarations : struct_member_declarations",
+    "struct_member_declarations : struct_member_declaration",
+    "struct_member_declarations : struct_member_declarations struct_member_declaration",
+    "struct_member_declaration : opt_modifiers struct_member_declarator",
+    "struct_member_declarator : field_declaration",
+    "struct_member_declarator : constant_declaration",
+    "struct_member_declarator : constructor_declaration",
+    "struct_member_declarator : method_declaration",
+    "struct_member_declarator : event_declaration",
+    "struct_member_declarator : type_spec_declaration",
+    "event_declaration : EVENT identifier AS type opt_implement_clause logical_end_of_line",
+    "$$17 :",
+    "enum_declaration : ENUM identifier opt_type_spec logical_end_of_line opt_enum_member_declarations $$17 END ENUM logical_end_of_line",
+    "opt_enum_member_declarations :",
+    "opt_enum_member_declarations : enum_member_declarations",
+    "enum_member_declarations : enum_member_declaration",
+    "enum_member_declarations : enum_member_declarations enum_member_declaration",
+    "enum_member_declaration : opt_attributes identifier logical_end_of_line",
+    "$$18 :",
+    "enum_member_declaration : opt_attributes identifier $$18 ASSIGN expression logical_end_of_line",
+    "interface_property_declaration : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line",
+    "$$19 :",
+    "$$20 :",
+    "$$21 :",
+    "interface_declaration : INTERFACE identifier logical_end_of_line $$19 opt_interface_base $$20 interface_body $$21 END INTERFACE logical_end_of_line",
+    "opt_interface_base :",
+    "opt_interface_base : interface_bases",
+    "interface_bases : interface_base",
+    "interface_bases : interface_bases interface_base",
+    "interface_base : INHERITS type_list logical_end_of_line",
+    "interface_body : opt_interface_member_declarations",
+    "opt_interface_member_declarations :",
+    "opt_interface_member_declarations : interface_member_declarations",
+    "interface_member_declarations : interface_member_declaration",
+    "interface_member_declarations : interface_member_declarations interface_member_declaration",
+    "interface_member_declaration : opt_attributes opt_modifiers interface_member_declarator",
+    "interface_member_declarator : interface_method_declaration",
+    "interface_member_declarator : interface_property_declaration",
+    "interface_method_declaration : SUB identifier opt_params logical_end_of_line",
+    "interface_method_declaration : FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line",
+    "property_declaration : non_abstract_propery_declaration",
+    "$$22 :",
+    "non_abstract_propery_declaration : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line $$22 accessor_declarations END PROPERTY logical_end_of_line",
+    "opt_property_parameters :",
+    "opt_property_parameters : OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS",
+    "opt_implement_clause :",
+    "opt_implement_clause : IMPLEMENTS implement_clause_list",
+    "implement_clause_list : qualified_identifier",
+    "implement_clause_list : implement_clause_list COMMA qualified_identifier",
+    "accessor_declarations : get_accessor_declaration opt_set_accessor_declaration",
+    "accessor_declarations : set_accessor_declaration opt_get_accessor_declaration",
+    "opt_get_accessor_declaration :",
+    "opt_get_accessor_declaration : get_accessor_declaration",
+    "opt_set_accessor_declaration :",
+    "opt_set_accessor_declaration : set_accessor_declaration",
+    "$$23 :",
+    "$$24 :",
+    "get_accessor_declaration : opt_attributes GET logical_end_of_line $$23 begin_block $$24 opt_statement_list end_block END GET logical_end_of_line",
+    "$$25 :",
+    "set_accessor_declaration : opt_attributes SET opt_set_parameter logical_end_of_line $$25 begin_block opt_statement_list end_block END SET logical_end_of_line",
+    "opt_set_parameter :",
+    "opt_set_parameter : OPEN_PARENS CLOSE_PARENS",
+    "opt_set_parameter : OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS",
+    "field_declaration : opt_dim_stmt variable_declarators logical_end_of_line",
+    "opt_dim_stmt :",
+    "opt_dim_stmt : DIM",
+    "delegate_declaration : DELEGATE SUB identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS logical_end_of_line",
+    "delegate_declaration : DELEGATE FUNCTION identifier OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS opt_type_with_ranks logical_end_of_line",
+    "opt_evt_handler :",
+    "$$26 :",
+    "$$27 :",
+    "constructor_declaration : SUB NEW opt_params logical_end_of_line $$26 begin_block opt_statement_list end_block $$27 END SUB logical_end_of_line",
+    "opt_formal_parameter_list :",
+    "opt_formal_parameter_list : formal_parameter_list",
+    "formal_parameter_list : parameters",
+    "parameters : parameter",
+    "parameters : parameters COMMA parameter",
+    "parameter : opt_attributes opt_parameter_modifier identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer",
+    "opt_parameter_modifier :",
+    "opt_parameter_modifier : parameter_modifiers",
+    "parameter_modifiers : parameter_modifiers parameter_modifier",
+    "parameter_modifiers : parameter_modifier",
+    "parameter_modifier : BYREF",
+    "parameter_modifier : BYVAL",
+    "parameter_modifier : OPTIONAL",
+    "parameter_modifier : PARAM_ARRAY",
+    "opt_statement_list :",
+    "opt_statement_list : statement_list end_of_stmt",
+    "statement_list : statement",
+    "statement_list : statement_list end_of_stmt statement",
+    "block : begin_block opt_statement_list end_block",
+    "begin_block :",
+    "end_block :",
+    "statement : declaration_statement",
+    "statement : embedded_statement",
+    "statement : ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF expression",
+    "statement : REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF expression",
+    "statement : RAISEEVENT identifier opt_raise_event_args",
+    "opt_raise_event_args :",
+    "opt_raise_event_args : OPEN_PARENS opt_argument_list CLOSE_PARENS",
+    "embedded_statement : expression_statement",
+    "embedded_statement : selection_statement",
+    "embedded_statement : try_statement",
+    "embedded_statement : synclock_statement",
+    "embedded_statement : jump_statement",
+    "jump_statement : return_statement",
+    "jump_statement : goto_statement",
+    "jump_statement : throw_statement",
+    "goto_statement : GOTO label_name",
+    "throw_statement : THROW opt_expression",
+    "return_statement : RETURN opt_expression",
+    "synclock_statement : SYNCLOCK expression end_of_stmt block END SYNCLOCK",
+    "try_statement : try_catch",
+    "try_statement : try_catch_finally",
+    "try_catch : TRY end_of_stmt block opt_catch_clauses END TRY",
+    "try_catch_finally : TRY end_of_stmt block opt_catch_clauses FINALLY end_of_stmt block END TRY",
+    "opt_catch_clauses :",
+    "opt_catch_clauses : catch_clauses",
+    "catch_clauses : catch_clause",
+    "catch_clauses : catch_clauses catch_clause",
+    "opt_identifier :",
+    "opt_identifier : identifier",
+    "$$28 :",
+    "catch_clause : CATCH opt_catch_args end_of_stmt $$28 block",
+    "opt_catch_args :",
+    "opt_catch_args : catch_args",
+    "catch_args : identifier AS type",
+    "$$29 :",
+    "while_statement : WHILE $$29 boolean_expression end_of_stmt begin_block opt_statement_list end_block END WHILE",
+    "selection_statement : if_statement",
+    "if_statement : IF boolean_expression opt_then end_of_stmt block END IF",
+    "if_statement : IF boolean_expression opt_then end_of_stmt block ELSE end_of_stmt block END IF",
+    "if_statement : IF boolean_expression opt_then end_of_stmt block else_if_statement_rest",
+    "else_if_statement_rest : ELSEIF boolean_expression opt_then end_of_stmt block END IF",
+    "else_if_statement_rest : ELSEIF boolean_expression opt_then end_of_stmt block ELSE end_of_stmt block END IF",
+    "else_if_statement_rest : ELSEIF boolean_expression opt_then end_of_stmt block else_if_statement_rest",
+    "opt_then :",
+    "opt_then : THEN",
+    "case_clauses : case_clause",
+    "case_clauses : case_clauses COMMA case_clause",
+    "case_clause : opt_is comparison_operator expression",
+    "case_clause : expression",
+    "opt_is :",
+    "opt_is : IS",
+    "comparison_operator : OP_LT",
+    "comparison_operator : OP_GT",
+    "comparison_operator : OP_LE",
+    "comparison_operator : OP_NE",
+    "opt_case :",
+    "opt_case : CASE",
+    "expression_statement : statement_expression",
+    "statement_expression : invocation_expression",
+    "statement_expression : object_creation_expression",
+    "statement_expression : assignment_expression",
+    "object_creation_expression : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS",
+    "object_creation_expression : NEW type",
+    "new_expression : object_creation_expression",
+    "declaration_statement : local_variable_declaration",
+    "declaration_statement : local_constant_declaration",
+    "local_variable_declaration : DIM variable_declarators",
+    "local_constant_declaration : CONST constant_declarators",
+    "constant_declarators : constant_declarator",
+    "constant_declarators : constant_declarators COMMA constant_declarator",
+    "constant_declarator : variable_name opt_type_decl opt_variable_initializer",
+    "variable_declarators : variable_declarator",
+    "variable_declarators : variable_declarators COMMA variable_declarator",
+    "variable_declarator : variable_names opt_type_decl opt_variable_initializer",
+    "variable_names : variable_name",
+    "variable_names : variable_names COMMA variable_name",
+    "variable_name : identifier opt_type_character opt_array_name_modifier",
+    "opt_type_spec :",
+    "opt_type_spec : AS type",
+    "opt_type_with_ranks : opt_type_spec",
+    "opt_type_decl : opt_type_with_ranks",
+    "opt_type_decl : AS NEW type",
+    "opt_type_decl : AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS",
+    "opt_array_name_modifier :",
+    "opt_variable_initializer :",
+    "opt_variable_initializer : ASSIGN variable_initializer",
+    "variable_initializer : expression",
+    "variable_initializer : array_initializer",
+    "array_initializer : OPEN_BRACE CLOSE_BRACE",
+    "array_initializer : OPEN_BRACE variable_initializer_list CLOSE_BRACE",
+    "variable_initializer_list : variable_initializer",
+    "variable_initializer_list : variable_initializer_list COMMA variable_initializer",
+    "opt_rank_specifiers :",
+    "opt_rank_specifiers : rank_specifiers",
+    "rank_specifiers : rank_specifier",
+    "rank_specifiers : rank_specifiers rank_specifier",
+    "rank_specifier : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS",
+    "opt_dim_specifiers :",
+    "opt_dim_specifiers : expression",
+    "opt_dim_specifiers : opt_dim_specifiers COMMA expression",
+    "opt_dim_specifiers : opt_dim_specifiers COMMA",
+    "primary_expression : literal",
+    "primary_expression : parenthesized_expression",
+    "primary_expression : this_access",
+    "primary_expression : base_access",
+    "primary_expression : qualified_identifier",
+    "primary_expression : get_type_expression",
+    "primary_expression : member_access",
+    "primary_expression : invocation_expression",
+    "primary_expression : new_expression",
+    "primary_expression : cast_expression",
+    "literal : boolean_literal",
+    "literal : integer_literal",
+    "literal : real_literal",
+    "literal : LITERAL_CHARACTER",
+    "literal : LITERAL_STRING",
+    "literal : NOTHING",
+    "real_literal : LITERAL_SINGLE",
+    "real_literal : LITERAL_DOUBLE",
+    "real_literal : LITERAL_DECIMAL",
+    "integer_literal : LITERAL_INTEGER",
+    "boolean_literal : TRUE",
+    "boolean_literal : FALSE",
+    "parenthesized_expression : OPEN_PARENS expression CLOSE_PARENS",
+    "member_access : primary_expression DOT identifier",
+    "member_access : predefined_type DOT identifier",
+    "predefined_type : builtin_types",
+    "invocation_expression : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS",
+    "invocation_expression : CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS",
+    "base_access : MYBASE DOT IDENTIFIER",
+    "opt_argument_list : argument_list",
+    "argument_list : argument",
+    "argument_list : argument_list COMMA argument",
+    "argument : expression",
+    "argument : BYREF variable_reference",
+    "argument :",
+    "argument : ADDRESSOF expression",
+    "variable_reference : expression",
+    "expression : conditional_xor_expression",
+    "opt_expression :",
+    "opt_expression : expression",
+    "this_access : ME",
+    "this_access : MYCLASS",
+    "cast_expression : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS",
+    "cast_expression : CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS",
+    "cast_expression : cast_operator OPEN_PARENS expression CLOSE_PARENS",
+    "cast_operator : CBOOL",
+    "cast_operator : CBYTE",
+    "cast_operator : CCHAR",
+    "cast_operator : CDBL",
+    "cast_operator : CDEC",
+    "cast_operator : CINT",
+    "cast_operator : CLNG",
+    "cast_operator : COBJ",
+    "cast_operator : CSHORT",
+    "cast_operator : CSNG",
+    "cast_operator : CSTR",
+    "get_type_expression : GETTYPE OPEN_PARENS type CLOSE_PARENS",
+    "exponentiation_expression : primary_expression",
+    "exponentiation_expression : exponentiation_expression OP_EXP primary_expression",
+    "prefixed_unary_expression : exponentiation_expression",
+    "prefixed_unary_expression : PLUS prefixed_unary_expression",
+    "prefixed_unary_expression : MINUS prefixed_unary_expression",
+    "multiplicative_expression : prefixed_unary_expression",
+    "multiplicative_expression : multiplicative_expression STAR prefixed_unary_expression",
+    "multiplicative_expression : multiplicative_expression DIV prefixed_unary_expression",
+    "integer_division_expression : multiplicative_expression",
+    "integer_division_expression : integer_division_expression OP_IDIV multiplicative_expression",
+    "mod_expression : integer_division_expression",
+    "mod_expression : mod_expression MOD integer_division_expression",
+    "additive_expression : mod_expression",
+    "additive_expression : additive_expression PLUS mod_expression",
+    "additive_expression : additive_expression MINUS mod_expression",
+    "concat_expression : additive_expression",
+    "concat_expression : concat_expression OP_CONCAT additive_expression",
+    "shift_expression : concat_expression",
+    "shift_expression : shift_expression OP_SHIFT_LEFT concat_expression",
+    "shift_expression : shift_expression OP_SHIFT_RIGHT concat_expression",
+    "relational_expression : shift_expression",
+    "relational_expression : relational_expression ASSIGN shift_expression",
+    "relational_expression : relational_expression OP_NE shift_expression",
+    "relational_expression : relational_expression OP_LT shift_expression",
+    "relational_expression : relational_expression OP_GT shift_expression",
+    "relational_expression : relational_expression OP_LE shift_expression",
+    "relational_expression : relational_expression OP_GE shift_expression",
+    "relational_expression : relational_expression IS shift_expression",
+    "relational_expression : TYPEOF shift_expression IS type",
+    "negation_expression : relational_expression",
+    "negation_expression : NOT negation_expression",
+    "conditional_and_expression : negation_expression",
+    "conditional_and_expression : conditional_and_expression AND negation_expression",
+    "conditional_and_expression : conditional_and_expression ANDALSO negation_expression",
+    "conditional_or_expression : conditional_and_expression",
+    "conditional_or_expression : conditional_or_expression OR conditional_and_expression",
+    "conditional_or_expression : conditional_or_expression ORELSE conditional_and_expression",
+    "conditional_xor_expression : conditional_or_expression",
+    "conditional_xor_expression : conditional_xor_expression XOR conditional_or_expression",
+    "assignment_expression : prefixed_unary_expression ASSIGN expression",
+    "assignment_expression : prefixed_unary_expression STAR ASSIGN expression",
+    "assignment_expression : prefixed_unary_expression DIV ASSIGN expression",
+    "assignment_expression : prefixed_unary_expression PLUS ASSIGN expression",
+    "assignment_expression : prefixed_unary_expression MINUS ASSIGN expression",
+    "assignment_expression : prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression",
+    "assignment_expression : prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression",
+    "assignment_expression : prefixed_unary_expression OP_CONCAT ASSIGN expression",
+    "assignment_expression : prefixed_unary_expression OP_EXP ASSIGN expression",
+    "assignment_expression : prefixed_unary_expression ASSIGN ADDRESSOF expression",
+    "constant_expression : expression",
+    "boolean_expression : expression",
+    "type : namespace_or_type_name",
+    "type : builtin_types",
+    "type_list : type",
+    "type_list : type_list COMMA type",
+    "namespace_or_type_name : qualified_identifier",
+    "builtin_types : OBJECT",
+    "builtin_types : primitive_type",
+    "primitive_type : numeric_type",
+    "primitive_type : BOOLEAN",
+    "primitive_type : CHAR",
+    "primitive_type : STRING",
+    "numeric_type : integral_type",
+    "numeric_type : floating_point_type",
+    "numeric_type : DECIMAL",
+    "integral_type :",
+    "integral_type : BYTE",
+    "integral_type : SHORT",
+    "integral_type : INTEGER",
+    "integral_type : LONG",
+    "floating_point_type : SINGLE",
+    "floating_point_type : DOUBLE",
+    "pp_directive : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL",
+    "pp_directive : HASH IDENTIFIER LITERAL_STRING EOL",
+    "pp_directive : HASH END IDENTIFIER EOL",
+    "pp_directive : HASH CONST IDENTIFIER ASSIGN boolean_literal EOL",
+    "$$30 :",
+    "pp_directive : HASH IF $$30 boolean_literal opt_then EOL",
+    "$$31 :",
+    "pp_directive : HASH ELSEIF $$31 boolean_literal opt_then EOL",
+    "$$32 :",
+    "pp_directive : HASH ELSE $$32 EOL",
+    "$$33 :",
+    "pp_directive : HASH END IF $$33 EOL",
+    "pp_directive : HASH error EOL",
+  };
+  protected static  string [] yyNames = {    
+    "end-of-file",null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,"'!'",null,"'#'","'$'","'%'","'&'",
+    null,"'('","')'","'*'","'+'","','","'-'","'.'","'/'",null,null,null,
+    null,null,null,null,null,null,null,"':'",null,"'<'","'='","'>'","'?'",
+    "'@'",null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    "'['","'\\\\'","']'","'^'",null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,"'{'",null,"'}'",null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,null,null,null,null,null,null,null,null,null,null,null,null,null,
+    null,"EOF","NONE","ERROR","ADDHANDLER","ADDRESSOF","ALIAS","AND",
+    "ANDALSO","ANSI","AS","ASSEMBLY","AUTO","BINARY","BOOLEAN","BYREF",
+    "BYTE","BYVAL","CALL","CASE","CATCH","CBOOL","CBYTE","CCHAR","CDATE",
+    "CDEC","CDBL","CHAR","CINT","CLASS","CLNG","COBJ","COMPARE","CONST",
+    "CSHORT","CSNG","CSTR","CTYPE","DATE","DECIMAL","DECLARE","DEFAULT",
+    "DELEGATE","DIM","DIRECTCAST","DO","DOUBLE","EACH","ELSE","ELSEIF",
+    "END","ENDIF","ENUM","EOL","ERASE","EVENT","EXIT","EXPLICIT","FALSE",
+    "FINALLY","FOR","FRIEND","FUNCTION","GET","GETTYPE","GOSUB","GOTO",
+    "HANDLES","IF","IMPLEMENTS","IMPORTS","IN","INHERITS","INTEGER",
+    "INTERFACE","IS","LET","LIB","LIKE","LONG","LOOP","ME","MOD","MODULE",
+    "MUSTINHERIT","MUSTOVERRIDE","MYBASE","MYCLASS","NAMESPACE","NEW",
+    "NEXT","NOT","NOTHING","NOTINHERITABLE","NOTOVERRIDABLE","OBJECT",
+    "OFF","ON","OPTION","OPTIONAL","OR","ORELSE","OVERLOADS",
+    "OVERRIDABLE","OVERRIDES","PARAM_ARRAY","PRESERVE","PRIVATE",
+    "PROPERTY","PROTECTED","PUBLIC","RAISEEVENT","READONLY","REDIM","REM",
+    "REMOVEHANDLER","RESUME","RETURN","SELECT","SET","SHADOWS","SHARED",
+    "SHORT","SINGLE","SIZEOF","STATIC","STEP","STOP","STRICT","STRING",
+    "STRUCTURE","SUB","SYNCLOCK","TEXT","THEN","THROW","TO","TRUE","TRY",
+    "TYPEOF","UNICODE","UNTIL","VARIANT","WEND","WHEN","WHILE","WITH",
+    "WITHEVENTS","WRITEONLY","XOR","YIELD","HASH","OPEN_BRACKET",
+    "CLOSE_BRACKET","OPEN_PARENS","OPEN_BRACE","CLOSE_BRACE",
+    "CLOSE_PARENS","DOT","COMMA","COLON","PLUS","MINUS","ASSIGN","OP_LT",
+    "OP_GT","STAR","DIV","OP_EXP","INTERR","OP_IDIV","OP_CONCAT",
+    "EXCLAMATION","PERCENT","LONGTYPECHAR","AT_SIGN","SINGLETYPECHAR",
+    "NUMBER_SIGN","DOLAR_SIGN","ATTR_ASSIGN","\":=\"","OP_LE","\"<=\"",
+    "OP_GE","\">=\"","OP_NE","\"<>\"","OP_XOR","\"xor\"","OP_SHIFT_LEFT",
+    "\"<<\"","OP_SHIFT_RIGHT","\">>\"","LITERAL_INTEGER",
+    "\"int literal\"","LITERAL_SINGLE","\"float literal\"",
+    "LITERAL_DOUBLE","\"double literal\"","LITERAL_DECIMAL",
+    "\"decimal literal\"","LITERAL_CHARACTER","\"character literal\"",
+    "LITERAL_STRING","\"string literal\"","LITERAL_DATE",
+    "\"datetime literal\"","IDENTIFIER","LOWPREC","OP_OR","OP_AND",
+    "BITWISE_OR","BITWISE_AND","BITWISE_NOT","CARRET","UMINUS","OP_INC",
+    "OP_DEC","HIGHPREC","label_name",
+  };
+
+  /** index-checked interface to yyNames[].
+      @param token single character or %token value.
+      @return token name or [illegal] or [unknown].
+    */
+  public static string yyname (int token) {
+    if ((token < 0) || (token > yyNames.Length)) return "[illegal]";
+    string name;
+    if ((name = yyNames[token]) != null) return name;
+    return "[unknown]";
+  }
+
+  /** computes list of expected tokens on error by tracing the tables.
+      @param state for which to compute the list.
+      @return list of token names.
+    */
+  protected string[] yyExpecting (int state) {
+    int token, n, len = 0;
+    bool[] ok = new bool[yyNames.Length];
+
+    if ((n = yySindex[state]) != 0)
+      for (token = n < 0 ? -n : 0;
+           (token < yyNames.Length) && (n+token < yyTable.Length); ++ token)
+        if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) {
+          ++ len;
+          ok[token] = true;
+        }
+    if ((n = yyRindex[state]) != 0)
+      for (token = n < 0 ? -n : 0;
+           (token < yyNames.Length) && (n+token < yyTable.Length); ++ token)
+        if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) {
+          ++ len;
+          ok[token] = true;
+        }
+
+    string [] result = new string[len];
+    for (n = token = 0; n < len;  ++ token)
+      if (ok[token]) result[n++] = yyNames[token];
+    return result;
+  }
+
+  /** the generated parser, with debugging messages.
+      Maintains a state and a value stack, currently with fixed maximum size.
+      @param yyLex scanner.
+      @param yydebug debug message writer implementing yyDebug, or null.
+      @return result of the last reduction, if any.
+      @throws yyException on irrecoverable parse error.
+    */
+  internal Object yyparse (yyParser.yyInput yyLex, Object yyd)
+                                {
+    this.debug = (yydebug.yyDebug)yyd;
+    return yyparse(yyLex);
+  }
+
+  /** initial size and increment of the state/value stack [default 256].
+      This is not final so that it can be overwritten outside of invocations
+      of yyparse().
+    */
+  protected int yyMax;
+
+  /** executed at the beginning of a reduce action.
+      Used as $$ = yyDefault($1), prior to the user-specified action, if any.
+      Can be overwritten to provide deep copy, etc.
+      @param first value for $1, or null.
+      @return first.
+    */
+  protected Object yyDefault (Object first) {
+    return first;
+  }
+
+  /** the generated parser.
+      Maintains a state and a value stack, currently with fixed maximum size.
+      @param yyLex scanner.
+      @return result of the last reduction, if any.
+      @throws yyException on irrecoverable parse error.
+    */
+  internal Object yyparse (yyParser.yyInput yyLex)
+                               {
+    if (yyMax <= 0) yyMax = 256;                       // initial size
+    int yyState = 0;                                   // state stack ptr
+    int [] yyStates = new int[yyMax];                  // state stack 
+    Object yyVal = null;                               // value stack ptr
+    Object [] yyVals = new Object[yyMax];              // value stack
+    int yyToken = -1;                                  // current input
+    int yyErrorFlag = 0;                               // #tks to shift
+
+    int yyTop = 0;
+    goto skip;
+    yyLoop:
+    yyTop++;
+    skip:
+    for (;; ++ yyTop) {
+      if (yyTop >= yyStates.Length) {                  // dynamically increase
+        int[] i = new int[yyStates.Length+yyMax];
+        yyStates.CopyTo (i, 0);
+        yyStates = i;
+        Object[] o = new Object[yyVals.Length+yyMax];
+        yyVals.CopyTo (o, 0);
+        yyVals = o;
+      }
+      yyStates[yyTop] = yyState;
+      yyVals[yyTop] = yyVal;
+      if (debug != null) debug.push(yyState, yyVal);
+
+      yyDiscarded: for (;;) {  // discarding a token does not change stack
+        int yyN;
+        if ((yyN = yyDefRed[yyState]) == 0) {  // else [default] reduce (yyN)
+          if (yyToken < 0) {
+            yyToken = yyLex.advance() ? yyLex.token() : 0;
+            if (debug != null)
+              debug.lex(yyState, yyToken, yyname(yyToken), yyLex.value());
+          }
+          if ((yyN = yySindex[yyState]) != 0 && ((yyN += yyToken) >= 0)
+              && (yyN < yyTable.Length) && (yyCheck[yyN] == yyToken)) {
+            if (debug != null)
+              debug.shift(yyState, yyTable[yyN], yyErrorFlag-1);
+            yyState = yyTable[yyN];            // shift to yyN
+            yyVal = yyLex.value();
+            yyToken = -1;
+            if (yyErrorFlag > 0) -- yyErrorFlag;
+            goto yyLoop;
+          }
+          if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0
+              && yyN < yyTable.Length && yyCheck[yyN] == yyToken)
+            yyN = yyTable[yyN];                        // reduce (yyN)
+          else
+            switch (yyErrorFlag) {
+  
+            case 0:
+              yyerror(String.Format ("syntax error, got token `{0}'", yyname (yyToken)), yyExpecting(yyState));
+              if (debug != null) debug.error("syntax error");
+              goto case 1;
+            case 1: case 2:
+              yyErrorFlag = 3;
+              do {
+                if ((yyN = yySindex[yyStates[yyTop]]) != 0
+                    && (yyN += Token.yyErrorCode) >= 0 && yyN < yyTable.Length
+                    && yyCheck[yyN] == Token.yyErrorCode) {
+                  if (debug != null)
+                    debug.shift(yyStates[yyTop], yyTable[yyN], 3);
+                  yyState = yyTable[yyN];
+                  yyVal = yyLex.value();
+                  goto yyLoop;
+                }
+                if (debug != null) debug.pop(yyStates[yyTop]);
+              } while (-- yyTop >= 0);
+              if (debug != null) debug.reject();
+              throw new yyParser.yyException("irrecoverable syntax error");
+  
+            case 3:
+              if (yyToken == 0) {
+                if (debug != null) debug.reject();
+                throw new yyParser.yyException("irrecoverable syntax error at end-of-file");
+              }
+              if (debug != null)
+                debug.discard(yyState, yyToken, yyname(yyToken),
+                                                       yyLex.value());
+              yyToken = -1;
+              goto yyDiscarded;                // leave stack alone
+            }
+        }
+        int yyV = yyTop + 1-yyLen[yyN];
+        if (debug != null)
+          debug.reduce(yyState, yyStates[yyV-1], yyN, yyRule[yyN], yyLen[yyN]);
+        yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]);
+        switch (yyN) {
+case 5:
+#line 753 "mb-parser.jay"
+  {
+               yyVal=yyVals[-1+yyTop];
+         }
+  break;
+case 6:
+#line 761 "mb-parser.jay"
+  {
+               /* ????? */ ;
+         }
+  break;
+case 14:
+#line 784 "mb-parser.jay"
+  {
+                 yyVal = (object)true;
+         }
+  break;
+case 15:
+#line 788 "mb-parser.jay"
+  {
+                 yyVal = (object)true;
+         }
+  break;
+case 16:
+#line 792 "mb-parser.jay"
+  {
+                 yyVal = (object)false;
+         }
+  break;
+case 17:
+#line 799 "mb-parser.jay"
+  {
+                 yyVal = (object)true;
+         }
+  break;
+case 18:
+#line 803 "mb-parser.jay"
+  {
+                 yyVal = (object)false;
+         }
+  break;
+case 19:
+#line 810 "mb-parser.jay"
+  {
+/*             if (!UseExtendedSyntax)*/
+/*                     OptionExplicit = (bool)$3;*/
+/*             else*/
+/*                     Report.Warning (*/
+/*                             9999, lexer.Location, */
+/*                             "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");*/
+         }
+  break;
+case 20:
+#line 823 "mb-parser.jay"
+  {
+/*             if (!UseExtendedSyntax)*/
+/*                     OptionStrict = (bool)$3;*/
+/*             else*/
+/*                     Report.Warning (*/
+/*                             9999, lexer.Location, */
+/*                             "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");*/
+         }
+  break;
+case 21:
+#line 835 "mb-parser.jay"
+  {
+/*             OptionCompareBinary = (bool)$3;*/
+         }
+  break;
+case 26:
+#line 852 "mb-parser.jay"
+  {
+/*             FIXME: Need to check declaration qualifiers for multi-file compilation*/
+/*             FIXME: Qualifiers cannot be applied to namespaces*/
+               allow_global_attribs = false;
+         }
+  break;
+case 27:
+#line 858 "mb-parser.jay"
+  {
+               current_namespace.DeclarationFound = true;
+         }
+  break;
+case 28:
+#line 862 "mb-parser.jay"
+  {
+                 /* FIXME: Need to check declaration qualifiers for multi-file compilation*/
+                 allow_global_attribs = false;
+         }
+  break;
+case 29:
+#line 867 "mb-parser.jay"
+  {
+               string name = "";
+               int mod_flags;
+
+               if (yyVals[0+yyTop] is Class){
+                       Class c = (Class) yyVals[0+yyTop];
+                       mod_flags = c.ModFlags;
+                       name = c.Name;
+               } else if (yyVals[0+yyTop] is Struct){
+                       Struct s = (Struct) yyVals[0+yyTop];
+                       mod_flags = s.ModFlags;
+                       name = s.Name;
+               } else
+                       break;
+
+               if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
+                       Report.Error (
+                               1527, lexer.Location, 
+                               "Namespace elements cant be explicitly " +
+                               "declared private or protected in `" + name + "'");
+               }
+               current_namespace.DeclarationFound = true;
+         }
+  break;
+case 36:
+#line 902 "mb-parser.jay"
+  { yyVal = TypeManager.system_int32_expr; }
+  break;
+case 37:
+#line 903 "mb-parser.jay"
+  { yyVal = TypeManager.system_int64_expr; }
+  break;
+case 38:
+#line 904 "mb-parser.jay"
+  { yyVal = TypeManager.system_decimal_expr; }
+  break;
+case 39:
+#line 905 "mb-parser.jay"
+  { yyVal = TypeManager.system_single_expr; }
+  break;
+case 40:
+#line 906 "mb-parser.jay"
+  { yyVal = TypeManager.system_double_expr; }
+  break;
+case 41:
+#line 907 "mb-parser.jay"
+  { yyVal = TypeManager.system_string_expr; }
+  break;
+case 42:
+#line 911 "mb-parser.jay"
+  { yyVal = null; }
+  break;
+case 43:
+#line 912 "mb-parser.jay"
+  { yyVal = yyVals[0+yyTop]; }
+  break;
+case 44:
+#line 918 "mb-parser.jay"
+  {
+               yyVal = new MemberName ((string) yyVals[0+yyTop]);
+       }
+  break;
+case 45:
+#line 922 "mb-parser.jay"
+  {
+               yyVal = new MemberName ((MemberName) yyVals[-2+yyTop], (string) yyVals[0+yyTop], null);
+         }
+  break;
+case 53:
+#line 948 "mb-parser.jay"
+  {
+               string name = ((MemberName) yyVals[0+yyTop]).GetName ();
+               current_namespace.Using (name, lexer.Location);
+       }
+  break;
+case 54:
+#line 953 "mb-parser.jay"
+  {
+                 current_namespace.UsingAlias ((string) yyVals[-2+yyTop], (MemberName) yyVals[0+yyTop], lexer.Location);
+       }
+  break;
+case 55:
+#line 960 "mb-parser.jay"
+  { yyVal = Parameters.EmptyReadOnlyParameters; }
+  break;
+case 56:
+#line 961 "mb-parser.jay"
+  { yyVal = Parameters.EmptyReadOnlyParameters; }
+  break;
+case 57:
+#line 962 "mb-parser.jay"
+  { yyVal = yyVals[-1+yyTop]; }
+  break;
+case 58:
+#line 967 "mb-parser.jay"
+  { 
+                 current_attributes = null;
+         }
+  break;
+case 59:
+#line 971 "mb-parser.jay"
+  { 
+               yyVal = yyVals[0+yyTop]; 
+               local_attrib_section_added = false;
+               current_attributes = (Attributes) yyVals[0+yyTop];
+         }
+  break;
+case 60:
+#line 980 "mb-parser.jay"
+  { 
+               yyVal = yyVals[0+yyTop];
+               if (yyVals[0+yyTop] == null) {
+                       expecting_local_attribs = false;
+                       expecting_global_attribs = false;
+                       break;
+               }
+               
+               if (expecting_local_attribs) {
+                       local_attrib_section_added = true;
+                       allow_global_attribs = false;
+
+                       yyVal = new Attributes ((ArrayList) yyVals[0+yyTop]);
+               }       
+
+               if (expecting_global_attribs) {
+                       yyVal = null;
+                       CodeGen.AddGlobalAttributes ((ArrayList) yyVals[0+yyTop]);
+               }
+
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
+         }
+  break;
+case 61:
+#line 1004 "mb-parser.jay"
+  {
+               yyVal = lexer.Location;
+          }
+  break;
+case 62:
+#line 1008 "mb-parser.jay"
+  {
+               yyVal = yyVals[-2+yyTop];
+               if (yyVals[0+yyTop] != null) {
+                       ArrayList attrs = (ArrayList) yyVals[0+yyTop];
+
+                       if (expecting_local_attribs) {
+                               if (local_attrib_section_added) {
+                                       expecting_local_attribs = false;
+                                       expecting_global_attribs = false;
+                                       Report.Error (30205, (Location) yyVals[-1+yyTop], "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
+                                       break;
+                               }
+
+                               if (yyVals[-2+yyTop] == null)
+                                       yyVal = new Attributes (attrs);
+                               else 
+                                       ((Attributes) yyVals[-2+yyTop]).AddAttributes (attrs);
+
+                               local_attrib_section_added = true;
+                               allow_global_attribs = false;
+                       }
+
+                       if (expecting_global_attribs) {
+                               yyVal = null;
+                               CodeGen.AddGlobalAttributes ((ArrayList) yyVals[0+yyTop]);
+                       }
+               }       
+
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
+         }
+  break;
+case 63:
+#line 1043 "mb-parser.jay"
+  {
+               yyVal = null;
+               if (yyVals[-2+yyTop] != null) {
+                       if (expecting_global_attribs && !(bool) yyVals[0+yyTop]) {
+                               Report.Error (30205, lexer.Location, "End of statement expected");
+                               break;
+                       }
+                       
+                       if (expecting_local_attribs)  {
+                               if ((bool) yyVals[0+yyTop]) {
+                                       Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement.");
+                                       break;
+                               }
+                       }
+
+                       yyVal = yyVals[-2+yyTop];
+               }
+         }
+  break;
+case 64:
+#line 1064 "mb-parser.jay"
+  { yyVal = false; }
+  break;
+case 65:
+#line 1065 "mb-parser.jay"
+  { yyVal = true; }
+  break;
+case 66:
+#line 1070 "mb-parser.jay"
+  {
+               ArrayList attrs = null;
+               if (yyVals[0+yyTop] != null) {
+                       attrs = new ArrayList ();
+                       attrs.Add (yyVals[0+yyTop]);
+               }
+               yyVal = attrs;
+         }
+  break;
+case 67:
+#line 1079 "mb-parser.jay"
+  {
+               ArrayList attrs = null;
+               
+               if (yyVals[0+yyTop] != null) {
+                       attrs = (yyVals[-2+yyTop] == null) ? new ArrayList () : (ArrayList) yyVals[-2+yyTop];
+                       attrs.Add (yyVals[0+yyTop]);
+               }
+
+               yyVal = attrs;
+         }
+  break;
+case 68:
+#line 1093 "mb-parser.jay"
+  {
+               yyVal = lexer.Location;
+          }
+  break;
+case 69:
+#line 1097 "mb-parser.jay"
+  {
+               yyVal = null;
+               
+               if (expecting_global_attribs)
+                       Report.Error (32015, (Location) yyVals[-1+yyTop], "Expecting Assembly or Module attribute specifiers");
+               else {
+                       expecting_local_attribs = true;
+                       MemberName mname = (MemberName) yyVals[-2+yyTop];
+                       string name = mname.GetName ();
+
+                       yyVal = new Attribute (null, name, (ArrayList) yyVals[0+yyTop],
+                                           (Location) yyVals[-1+yyTop]);
+               }
+          }
+  break;
+case 70:
+#line 1112 "mb-parser.jay"
+  {
+               yyVal = lexer.Location;
+           }
+  break;
+case 71:
+#line 1117 "mb-parser.jay"
+  {
+                 yyVal = lexer.Location;
+          }
+  break;
+case 72:
+#line 1121 "mb-parser.jay"
+  {
+               yyVal = null;
+
+               string attribute_target = (string) yyVals[-5+yyTop];
+               if (attribute_target != "assembly" && attribute_target != "module") {
+                       Report.Error (29999, lexer.Location, "`" + (string)yyVals[-5+yyTop] + "' is an invalid attribute modifier");
+                       break;
+               }
+               if (!allow_global_attribs) {
+                       Report.Error (30637, (Location) yyVals[-4+yyTop], "Global attribute statements must precede any declarations in a file");
+                       break;
+               }
+
+               if (expecting_local_attribs) {
+                       Report.Error (30183, (Location) yyVals[-4+yyTop], "Global attributes cannot be combined with local attributes");
+                       break;
+               }                       
+
+               expecting_global_attribs = true;
+
+               MemberName mname = (MemberName) yyVals[-2+yyTop];
+               string aname = mname.GetName ();
+
+               yyVal = new Attribute (attribute_target, aname, (ArrayList) yyVals[0+yyTop], (Location) yyVals[-1+yyTop]);
+           }
+  break;
+case 73:
+#line 1150 "mb-parser.jay"
+  { yyVal = "assembly"; }
+  break;
+case 74:
+#line 1151 "mb-parser.jay"
+  { yyVal = "module"; }
+  break;
+case 76:
+#line 1157 "mb-parser.jay"
+  { yyVal = null; }
+  break;
+case 77:
+#line 1159 "mb-parser.jay"
+  {
+               yyVal = yyVals[-1+yyTop];
+         }
+  break;
+case 80:
+#line 1171 "mb-parser.jay"
+  {
+               ArrayList args = new ArrayList (4);
+               args.Add (yyVals[0+yyTop]);
+       
+               yyVal = args;
+         }
+  break;
+case 81:
+#line 1178 "mb-parser.jay"
+  {
+               ArrayList args = new ArrayList (4);
+               args.Add (yyVals[-2+yyTop]);
+               args.Add (yyVals[0+yyTop]);
+
+               yyVal = args;
+         }
+  break;
+case 82:
+#line 1186 "mb-parser.jay"
+  {
+               ArrayList args = new ArrayList (4);
+               args.Add (null);
+               args.Add (yyVals[0+yyTop]);
+               
+               yyVal = args;
+         }
+  break;
+case 83:
+#line 1197 "mb-parser.jay"
+  {
+               ArrayList args = new ArrayList ();
+               args.Add (new Argument ((Expression) yyVals[0+yyTop], Argument.AType.Expression));
+
+               yyVal = args;
+         }
+  break;
+case 84:
+#line 1204 "mb-parser.jay"
+  {
+               ArrayList args = (ArrayList) yyVals[-2+yyTop];
+               args.Add (new Argument ((Expression) yyVals[0+yyTop], Argument.AType.Expression));
+
+               yyVal = args;
+        }
+  break;
+case 85:
+#line 1214 "mb-parser.jay"
+  {
+               ArrayList args = new ArrayList ();
+               args.Add (yyVals[0+yyTop]);
+
+               yyVal = args;
+         }
+  break;
+case 86:
+#line 1221 "mb-parser.jay"
+  {      
+               ArrayList args = (ArrayList) yyVals[-2+yyTop];
+               args.Add (yyVals[0+yyTop]);
+
+               yyVal = args;
+         }
+  break;
+case 87:
+#line 1231 "mb-parser.jay"
+  {
+               yyVal = new DictionaryEntry (
+                       (string) yyVals[-2+yyTop], 
+                       new Argument ((Expression) yyVals[0+yyTop], Argument.AType.Expression));
+         }
+  break;
+case 88:
+#line 1240 "mb-parser.jay"
+  {
+               if (current_attributes != null) {
+                       Report.Error(1518, Lexer.Location, "Attributes cannot be applied to namespaces."
+                                       + " Expected class, delegate, enum, interface, or struct");
+               }
+
+               MemberName name = (MemberName) yyVals[-1+yyTop];
+
+               if ((current_namespace.Parent != null) && (name.Left != null)) {
+                       Report.Error (134, lexer.Location,
+                                     "Cannot use qualified namespace names in nested " +
+                                     "namespace declarations");
+               }
+
+               current_namespace = new NamespaceEntry (
+                       current_namespace, file, name.GetName (), lexer.Location);
+         }
+  break;
+case 89:
+#line 1259 "mb-parser.jay"
+  { 
+               current_namespace = current_namespace.Parent;
+         }
+  break;
+case 97:
+#line 1280 "mb-parser.jay"
+  {
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
+               MemberName name = MakeName (new MemberName ((string) yyVals[-1+yyTop]));
+               int mod_flags = current_modifiers;
+
+
+               current_class = new Class (current_namespace, current_container, name,
+                                          mod_flags, (Attributes) current_attributes, lexer.Location);
+
+
+               current_container = current_class;
+               RootContext.Tree.RecordDecl (name.GetName (true), current_class);
+         }
+  break;
+case 98:
+#line 1297 "mb-parser.jay"
+  {
+               ArrayList bases = (ArrayList) yyVals[-1+yyTop];
+               ArrayList ifaces = (ArrayList) yyVals[0+yyTop];
+
+               if (ifaces != null){
+                       if (bases != null)      
+                               bases.AddRange(ifaces);
+                       else
+                               bases = ifaces;
+               }
+
+               if (bases != null) {
+                       if (current_class.Name == "System.Object") {
+                               Report.Error (537, current_class.Location,
+                                             "The class System.Object cannot have a base " +
+                                             "class or implement an interface.");
+                       }
+                       current_class.Bases = (ArrayList) bases;
+               }
+
+               current_class.Register ();
+         }
+  break;
+case 99:
+#line 1321 "mb-parser.jay"
+  {
+               yyVal = current_class;
+
+               current_container = current_container.Parent;
+               current_class = current_container;
+         }
+  break;
+case 100:
+#line 1330 "mb-parser.jay"
+  { yyVal = null; }
+  break;
+case 101:
+#line 1331 "mb-parser.jay"
+  { yyVal = yyVals[-1+yyTop]; }
+  break;
+case 102:
+#line 1335 "mb-parser.jay"
+  { yyVal = null; }
+  break;
+case 103:
+#line 1336 "mb-parser.jay"
+  { yyVal = yyVals[-1+yyTop]; }
+  break;
+case 104:
+#line 1341 "mb-parser.jay"
+  { 
+               yyVal = (int) 0; 
+               current_modifiers = 0; 
+       }
+  break;
+case 105:
+#line 1346 "mb-parser.jay"
+  { 
+               yyVal = yyVals[0+yyTop]; 
+               current_modifiers = (int) yyVals[0+yyTop]; 
+       }
+  break;
+case 107:
+#line 1355 "mb-parser.jay"
+  { 
+               int m1 = (int) yyVals[-1+yyTop];
+               int m2 = (int) yyVals[0+yyTop];
+
+               if ((m1 & m2) != 0) {
+                       Location l = lexer.Location;
+                       Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
+               }
+               yyVal = (int) (m1 | m2);
+         }
+  break;
+case 108:
+#line 1368 "mb-parser.jay"
+  { yyVal = Modifiers.PUBLIC; }
+  break;
+case 109:
+#line 1369 "mb-parser.jay"
+  { yyVal = Modifiers.PROTECTED; }
+  break;
+case 110:
+#line 1370 "mb-parser.jay"
+  { yyVal = Modifiers.PRIVATE; }
+  break;
+case 111:
+#line 1371 "mb-parser.jay"
+  { yyVal = Modifiers.STATIC; }
+  break;
+case 112:
+#line 1372 "mb-parser.jay"
+  { yyVal = Modifiers.INTERNAL; }
+  break;
+case 113:
+#line 1373 "mb-parser.jay"
+  { yyVal = Modifiers.SEALED; }
+  break;
+case 114:
+#line 1374 "mb-parser.jay"
+  { yyVal = Modifiers.VIRTUAL; }
+  break;
+case 115:
+#line 1375 "mb-parser.jay"
+  { yyVal = Modifiers.NONVIRTUAL; }
+  break;
+case 116:
+#line 1376 "mb-parser.jay"
+  { yyVal = Modifiers.OVERRIDE; }
+  break;
+case 117:
+#line 1377 "mb-parser.jay"
+  { yyVal = Modifiers.NEW; }
+  break;
+case 118:
+#line 1378 "mb-parser.jay"
+  { yyVal = Modifiers.SHADOWS; }
+  break;
+case 119:
+#line 1379 "mb-parser.jay"
+  { yyVal = Modifiers.ABSTRACT; }
+  break;
+case 120:
+#line 1380 "mb-parser.jay"
+  { yyVal = Modifiers.READONLY; }
+  break;
+case 121:
+#line 1381 "mb-parser.jay"
+  { yyVal = Modifiers.DEFAULT; }
+  break;
+case 122:
+#line 1382 "mb-parser.jay"
+  { yyVal = Modifiers.WRITEONLY; }
+  break;
+case 123:
+#line 1387 "mb-parser.jay"
+  { 
+               MemberName name = MakeName(new MemberName ((string) yyVals[-1+yyTop]));
+               current_class = new VBModule (current_namespace, current_container, name, 
+                                           current_modifiers, current_attributes, lexer.Location);
+
+               current_container = current_class;
+               RootContext.Tree.RecordDecl(name.GetName (true), current_class);
+
+               current_class.Register ();
+         }
+  break;
+case 124:
+#line 1399 "mb-parser.jay"
+  {
+               yyVal = current_class;
+/*             FIXME: ?????*/
+/*             TypeManager.AddStandardModule (current_class);*/
+
+               current_container = current_container.Parent;
+               current_class = current_container;
+         }
+  break;
+case 129:
+#line 1422 "mb-parser.jay"
+  { 
+               current_modifiers = ((int)yyVals[0+yyTop]) | Modifiers.STATIC; 
+               bool explicit_static = (((int) yyVals[0+yyTop] & Modifiers.STATIC) > 0);
+               implicit_modifiers = (!explicit_static);
+          }
+  break;
+case 130:
+#line 1429 "mb-parser.jay"
+  {
+               implicit_modifiers = false;
+               yyVal = yyVals[-1+yyTop];
+          }
+  break;
+case 138:
+#line 1449 "mb-parser.jay"
+  {
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+               
+               int modflags = (int) current_modifiers;
+               
+               /* Structure members are Public by default                      */
+               if ((current_container is Struct) && (modflags == 0))
+                       modflags = Modifiers.PUBLIC;                    
+
+               ArrayList consts = (ArrayList) yyVals[-1+yyTop];
+               if(consts.Count > 0) 
+               {
+                       VariableDeclaration.FixupTypes ((ArrayList) yyVals[-1+yyTop]);
+                       VariableDeclaration.FixupArrayTypes ((ArrayList) yyVals[-1+yyTop]);
+
+                       foreach (VariableDeclaration constant in (ArrayList) yyVals[-1+yyTop]){
+                               Location l = constant.Location;
+                               Const c = new Const (current_class, 
+                                                    (Expression) constant.type, 
+                                                    (String) constant.identifier, 
+                                                    (Expression) constant.expression_or_array_initializer, 
+                                                    modflags, current_attributes, l);
+
+                               current_container.AddConstant (c);
+                       }
+               }
+       }
+  break;
+case 143:
+#line 1493 "mb-parser.jay"
+  {
+               yyVal = yyVals[0+yyTop];
+          }
+  break;
+case 153:
+#line 1571 "mb-parser.jay"
+  {
+               MemberName name = new MemberName ((string) yyVals[-1+yyTop]);
+
+               if ((current_container is Struct) && (current_modifiers == 0))
+                       current_modifiers = Modifiers.PUBLIC;           
+
+
+               GenericMethod generic = null;
+               Method method = new Method (current_class, generic, TypeManager.system_void_expr,
+                                           (int) current_modifiers, false, name, 
+                                           (Parameters) yyVals[0+yyTop], (Attributes) current_attributes, 
+                                           lexer.Location);
+
+               current_local_parameters = (Parameters) yyVals[0+yyTop];
+               yyVal = method;
+
+               iterator_container = (IIteratorContainer) method;
+         }
+  break;
+case 154:
+#line 1595 "mb-parser.jay"
+  {
+               Method method = (Method) yyVals[-9+yyTop];
+               Block b = (Block) yyVals[-3+yyTop];
+               const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
+
+               if (b == null){
+                       if ((method.ModFlags & extern_abstract) == 0){
+                               Report.Error (
+                                       501, lexer.Location,  current_container.MakeName (method.Name) +
+                                       "must declare a body because it is not marked abstract or extern");
+                       }
+               } else {
+                       if ((method.ModFlags & Modifiers.EXTERN) != 0){
+                               Report.Error (
+                                       179, lexer.Location, current_container.MakeName (method.Name) +
+                                       " is declared extern, but has a body");
+                       }
+               }
+
+               method.Block = (ToplevelBlock) yyVals[-3+yyTop];
+               current_container.AddMethod (method);
+
+               current_local_parameters = null;
+               iterator_container = null;
+         }
+  break;
+case 155:
+#line 1625 "mb-parser.jay"
+  {
+               MemberName name =  new MemberName ((string) yyVals[-3+yyTop]);
+               Expression rettype = (yyVals[0+yyTop] == null) ? ((yyVals[-2+yyTop] == null) ? TypeManager.system_object_expr : (Expression) yyVals[-2+yyTop] ) : (Expression) yyVals[0+yyTop];
+
+               GenericMethod generic = null;
+
+               Method method = new Method (current_class, generic, rettype, current_modifiers,
+                                           false, name,  (Parameters) yyVals[-1+yyTop], current_attributes,
+                                           lexer.Location);
+
+               current_local_parameters = (Parameters) yyVals[-1+yyTop];
+
+               yyVal = method;
+               iterator_container = method;
+         }
+  break;
+case 156:
+#line 1643 "mb-parser.jay"
+  { 
+               Method method = (Method) yyVals[-3+yyTop];
+
+               ArrayList retval = new ArrayList ();
+               retval.Add (new VariableDeclaration ((string) yyVals[-7+yyTop], method.Type, lexer.Location));
+               declare_local_variables (method.Type, retval, lexer.Location);
+         }
+  break;
+case 157:
+#line 1653 "mb-parser.jay"
+  {
+               Method method = (Method) yyVals[-9+yyTop];
+               Block b = (Block) yyVals[-3+yyTop];
+               const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
+
+               if (b == null){
+                       if ((method.ModFlags & extern_abstract) == 0){
+                               Report.Error (
+                                       501, lexer.Location,  current_container.MakeName (method.Name) +
+                                       "must declare a body because it is not marked abstract or extern");
+                       }
+               } else {
+                       if ((method.ModFlags & Modifiers.EXTERN) != 0){
+                               Report.Error (
+                                       179, lexer.Location, current_container.MakeName (method.Name) +
+                                       " is declared extern, but has a body");
+                       }
+               }
+
+               method.Block = (ToplevelBlock) b;
+               current_container.AddMethod (method);
+
+               current_local_parameters = null;
+               iterator_container = null;
+         }
+  break;
+case 158:
+#line 1683 "mb-parser.jay"
+  { 
+               MemberName name = MakeName (new MemberName ((string) yyVals[-2+yyTop]));
+
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
+               current_class = new Struct (current_namespace, current_container, name, current_modifiers,
+                                           current_attributes, lexer.Location);
+
+               current_container = current_class;
+               RootContext.Tree.RecordDecl (name.GetName (true), current_class);
+
+               if (yyVals[0+yyTop] != null)
+                       current_class.Bases = (ArrayList) yyVals[0+yyTop];
+
+               current_class.Register ();
+         }
+  break;
+case 159:
+#line 1701 "mb-parser.jay"
+  {
+               yyVal = current_class;
+
+               current_container = current_container.Parent;
+               current_class = current_container;
+         }
+  break;
+case 174:
+#line 1806 "mb-parser.jay"
+  {
+               VariableDeclaration var = new VariableDeclaration ((string) yyVals[-4+yyTop], (Expression) yyVals[-2+yyTop], lexer.Location);
+
+               MemberName name = new MemberName ((string) yyVals[-4+yyTop]);
+
+               Event e = new EventField (current_class, (Expression) yyVals[-2+yyTop], current_modifiers, false, name,
+                                         var.expression_or_array_initializer, current_attributes,
+                                         lexer.Location);
+
+               current_container.AddEvent (e);
+         }
+  break;
+case 175:
+#line 1860 "mb-parser.jay"
+  { 
+               Location enum_location = lexer.Location;
+
+               Expression base_type = TypeManager.system_int32_expr;
+               if ((Expression) yyVals[-2+yyTop] != null)
+                       base_type = (Expression) yyVals[-2+yyTop];
+
+               ArrayList enum_members = (ArrayList) yyVals[0+yyTop];
+               if (enum_members.Count == 0)
+                       Report.Error (30280, enum_location,
+                                     "Enum can not have empty member list");
+
+
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+                       
+               MemberName full_name = MakeName (new MemberName ((string) yyVals[-3+yyTop]));
+               Enum e = new Enum (current_namespace, current_container, base_type, 
+                                  (int) current_modifiers, full_name, 
+                                  (Attributes) current_attributes, enum_location);
+               
+               foreach (VariableDeclaration ev in (ArrayList) yyVals[0+yyTop]) {
+                       e.AddEnumMember (ev.identifier, 
+                                        (Expression) ev.expression_or_array_initializer,
+                                        ev.Location, ev.OptAttributes, ev.DocComment);
+               }
+
+               string name = full_name.GetName ();
+               current_container.AddEnum (e);
+               RootContext.Tree.RecordDecl (name, e);
+
+         }
+  break;
+case 177:
+#line 1896 "mb-parser.jay"
+  { yyVal = new ArrayList (4); }
+  break;
+case 178:
+#line 1897 "mb-parser.jay"
+  { yyVal = yyVals[0+yyTop]; }
+  break;
+case 179:
+#line 1902 "mb-parser.jay"
+  {
+               ArrayList l = new ArrayList ();
+
+               l.Add (yyVals[0+yyTop]);
+               yyVal = l;
+         }
+  break;
+case 180:
+#line 1909 "mb-parser.jay"
+  {
+               ArrayList l = (ArrayList) yyVals[-1+yyTop];
+
+               l.Add (yyVals[0+yyTop]);
+
+               yyVal = l;
+         }
+  break;
+case 181:
+#line 1920 "mb-parser.jay"
+  {
+               yyVal = new VariableDeclaration ((string) yyVals[-1+yyTop], null, lexer.Location, (Attributes) yyVals[-2+yyTop]);
+         }
+  break;
+case 182:
+#line 1924 "mb-parser.jay"
+  {
+                 yyVal = lexer.Location;
+         }
+  break;
+case 183:
+#line 1928 "mb-parser.jay"
+  { 
+               yyVal = new VariableDeclaration ((string) yyVals[-4+yyTop], yyVals[-1+yyTop], lexer.Location, (Attributes) yyVals[-5+yyTop]);
+         }
+  break;
+case 184:
+#line 2019 "mb-parser.jay"
+  {
+               get_implicit_value_parameter_type  = 
+                       (yyVals[-1+yyTop] == null) ? ((yyVals[-3+yyTop] == null) ? 
+                               TypeManager.system_object_expr : (Expression) yyVals[-3+yyTop] ) : (Expression) yyVals[-1+yyTop];
+
+               current_local_parameters = (Parameters) yyVals[-2+yyTop];
+               if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
+                       get_parameters = current_local_parameters.Copy (lexer.Location);
+                       set_parameters = current_local_parameters.Copy (lexer.Location);
+                       
+                       Parameter implicit_value_parameter = new Parameter (
+                                       get_implicit_value_parameter_type, "Value", Parameter.Modifier.NONE, null);
+                       
+                       set_parameters.AppendParameter (implicit_value_parameter);
+               }
+               else
+               {
+                       get_parameters = Parameters.EmptyReadOnlyParameters;
+                       set_parameters = new Parameters (null, null ,lexer.Location); 
+                       
+                       Parameter implicit_value_parameter = new Parameter (
+                                       get_implicit_value_parameter_type, "Value", Parameter.Modifier.NONE, null);
+                       
+                       set_parameters.AppendParameter (implicit_value_parameter);
+               }
+               lexer.PropertyParsing = true;
+               
+               Location loc = lexer.Location;
+               MemberName name = new MemberName ((string) yyVals[-4+yyTop]);
+
+               Accessor get_block = new Accessor (null, 0, null, loc); 
+               Accessor set_block = new Accessor (null, 0, null, loc); 
+
+               Property prop = new Property (current_class, get_implicit_value_parameter_type, 
+                                    (int) current_modifiers, true,
+                                    name, current_attributes, 
+                                    get_parameters, get_block, 
+                                    set_parameters, set_block, lexer.Location);
+               
+               current_container.AddProperty (prop);
+               
+               get_implicit_value_parameter_type = null;
+               set_implicit_value_parameter_type = null;
+               get_parameters = null;
+               set_parameters = null;
+               current_local_parameters = null;                        
+         }
+  break;
+case 185:
+#line 2105 "mb-parser.jay"
+  {
+               MemberName name = new MemberName ((string) yyVals[-1+yyTop]);
+
+               current_class = new Interface (current_namespace, current_container, 
+                                              name, (int) current_modifiers, 
+                                              (Attributes) current_attributes, lexer.Location);
+
+               current_container = current_class;
+               RootContext.Tree.RecordDecl (name.GetName (true), current_class);
+
+         }
+  break;
+case 186:
+#line 2117 "mb-parser.jay"
+  {
+               current_class.Bases = (ArrayList) yyVals[0+yyTop];
+               current_class.Register ();
+         }
+  break;
+case 187:
+#line 2122 "mb-parser.jay"
+  {
+               yyVal = current_class;
+
+               current_container = current_container.Parent;
+               current_class = current_container;
+         }
+  break;
+case 189:
+#line 2132 "mb-parser.jay"
+  { yyVal = null; }
+  break;
+case 190:
+#line 2133 "mb-parser.jay"
+  { yyVal = yyVals[0+yyTop]; }
+  break;
+case 192:
+#line 2139 "mb-parser.jay"
+  {
+               ArrayList bases = (ArrayList) yyVals[-1+yyTop];
+               bases.AddRange ((ArrayList) yyVals[0+yyTop]);
+               yyVal = bases;
+         }
+  break;
+case 193:
+#line 2147 "mb-parser.jay"
+  { yyVal = yyVals[-1+yyTop]; }
+  break;
+case 200:
+#line 2170 "mb-parser.jay"
+  { 
+               Method m = (Method) yyVals[0+yyTop];
+
+               current_container.AddMethod (m);
+         }
+  break;
+case 202:
+#line 2181 "mb-parser.jay"
+  {
+               MemberName name = (MemberName) new MemberName ((string) yyVals[-2+yyTop]);
+
+               GenericMethod generic = null;
+
+               yyVal = new Method (current_class, generic, TypeManager.system_void_expr, 
+                                (int) current_modifiers, true, name, (Parameters) yyVals[-1+yyTop],  
+                                (Attributes) current_attributes, lexer.Location);
+         }
+  break;
+case 203:
+#line 2192 "mb-parser.jay"
+  {
+               MemberName name = new MemberName ((string) yyVals[-4+yyTop]);
+               Expression return_type = (yyVals[-1+yyTop] == null) ? 
+                       ((yyVals[-3+yyTop] == null) ? TypeManager.system_object_expr : (Expression) yyVals[-3+yyTop] ) 
+                       : (Expression) yyVals[-1+yyTop];
+
+               GenericMethod generic = null;
+               yyVal = new Method (current_class, generic, return_type, (int) current_modifiers, 
+                                true, name, (Parameters) yyVals[-2+yyTop], (Attributes) current_attributes,
+                                lexer.Location);
+         }
+  break;
+case 205:
+#line 2268 "mb-parser.jay"
+  {
+               get_implicit_value_parameter_type  = 
+                       (yyVals[-2+yyTop] == null) ? ((yyVals[-4+yyTop] == null) ? 
+                               TypeManager.system_object_expr : (Expression) yyVals[-4+yyTop] ) : (Expression) yyVals[-2+yyTop];
+               get_implicit_value_parameter_name = (string) yyVals[-5+yyTop];
+               
+               current_local_parameters = (Parameters) yyVals[-3+yyTop];
+               if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
+                       get_parameters = current_local_parameters.Copy (lexer.Location);
+                       set_parameters = current_local_parameters.Copy (lexer.Location);
+               }
+               else
+               {
+                       get_parameters = Parameters.EmptyReadOnlyParameters;
+                       set_parameters = new Parameters (null, null ,lexer.Location);           
+               }
+               lexer.PropertyParsing = true;
+
+               yyVal = lexer.Location;
+         }
+  break;
+case 206:
+#line 2290 "mb-parser.jay"
+  {
+               lexer.PropertyParsing = false;
+
+               Property prop;
+               Pair pair = (Pair) yyVals[-3+yyTop];
+               
+               Accessor get_block = (Accessor) pair.First; 
+               Accessor set_block = (Accessor) pair.Second; 
+               
+               Location loc = lexer.Location;
+               MemberName name = new MemberName ((string) yyVals[-10+yyTop]);
+
+               /* FIXME: Implements Clause needs to be taken care of.*/
+
+               if ((current_container is Struct) && (current_modifiers == 0))
+                       current_modifiers = Modifiers.PUBLIC;                           
+
+
+               prop = new Property (current_class, get_implicit_value_parameter_type, 
+                                    (int) current_modifiers, false,
+                                    name, (Attributes) current_attributes, 
+                                    get_parameters, get_block, 
+                                    set_parameters, set_block, lexer.Location);
+               
+               current_container.AddProperty (prop);
+               get_implicit_value_parameter_type = null;
+               set_implicit_value_parameter_type = null;
+               get_parameters = null;
+               set_parameters = null;
+               current_local_parameters = null;
+         }
+  break;
+case 207:
+#line 2325 "mb-parser.jay"
+  {
+               yyVal = Parameters.EmptyReadOnlyParameters;
+         }
+  break;
+case 208:
+#line 2329 "mb-parser.jay"
+  {
+               yyVal = yyVals[-1+yyTop];
+         }
+  break;
+case 209:
+#line 2336 "mb-parser.jay"
+  {
+               yyVal = null;
+         }
+  break;
+case 210:
+#line 2340 "mb-parser.jay"
+  {
+               yyVal = yyVals[0+yyTop];
+         }
+  break;
+case 211:
+#line 2347 "mb-parser.jay"
+  {
+                 MemberName mname = (MemberName) yyVals[0+yyTop];
+                 ArrayList impl_list = new ArrayList ();
+                 impl_list.Add (mname.GetTypeExpression (lexer.Location));
+                 yyVal = impl_list;
+         }
+  break;
+case 212:
+#line 2354 "mb-parser.jay"
+  {
+                 MemberName mname = (MemberName) yyVals[0+yyTop];
+                 ArrayList impl_list = (ArrayList) yyVals[-2+yyTop];
+                 impl_list.Add (mname.GetTypeExpression (lexer.Location));
+                 yyVal = impl_list;
+         }
+  break;
+case 213:
+#line 2364 "mb-parser.jay"
+  { 
+               yyVal = new Pair (yyVals[-1+yyTop], yyVals[0+yyTop]);
+         }
+  break;
+case 214:
+#line 2368 "mb-parser.jay"
+  {
+               yyVal = new Pair (yyVals[0+yyTop], yyVals[-1+yyTop]);
+         }
+  break;
+case 215:
+#line 2374 "mb-parser.jay"
+  { yyVal = null; }
+  break;
+case 217:
+#line 2379 "mb-parser.jay"
+  { yyVal = null; }
+  break;
+case 219:
+#line 2385 "mb-parser.jay"
+  {
+               if ((current_modifiers & Modifiers.WRITEONLY) != 0)
+                       Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
+         
+               current_local_parameters = get_parameters;
+               
+               lexer.PropertyParsing = false;
+               
+         }
+  break;
+case 220:
+#line 2395 "mb-parser.jay"
+  {
+               ArrayList retval = new ArrayList ();
+               retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
+               declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);    
+         }
+  break;
+case 221:
+#line 2403 "mb-parser.jay"
+  {
+               yyVal = new Accessor ((ToplevelBlock) yyVals[-3+yyTop], (int) current_modifiers, 
+                                  (Attributes) yyVals[-10+yyTop], lexer.Location);
+
+               current_local_parameters = null;
+               lexer.PropertyParsing = true;
+         }
+  break;
+case 222:
+#line 2416 "mb-parser.jay"
+  {
+        if ((current_modifiers & Modifiers.READONLY) != 0)
+                       Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
+                       
+               Parameter implicit_value_parameter = new Parameter (
+                       set_implicit_value_parameter_type, 
+                       set_implicit_value_parameter_name, 
+                       Parameter.Modifier.NONE, null);
+
+               set_parameters.AppendParameter (implicit_value_parameter);
+               current_local_parameters = set_parameters;
+
+               lexer.PropertyParsing = false;
+         }
+  break;
+case 223:
+#line 2434 "mb-parser.jay"
+  {
+               yyVal = new Accessor ((ToplevelBlock) yyVals[-3+yyTop], (int) current_modifiers, 
+                                  (Attributes) yyVals[-10+yyTop], lexer.Location);
+               current_local_parameters = null;
+               lexer.PropertyParsing = true;
+         }
+  break;
+case 224:
+#line 2444 "mb-parser.jay"
+  {
+               set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; /* TypeManager.system_object_expr;*/
+               set_implicit_value_parameter_name = "Value";
+       }
+  break;
+case 225:
+#line 2449 "mb-parser.jay"
+  {
+               set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
+               set_implicit_value_parameter_name = "Value";
+       }
+  break;
+case 226:
+#line 2454 "mb-parser.jay"
+  {
+               Parameter.Modifier pm = (Parameter.Modifier)yyVals[-3+yyTop];
+               if ((pm | Parameter.Modifier.VAL) != 0)
+                       Report.Error (31065, 
+                               lexer.Location, 
+                               "Set cannot have a paremeter modifier other than 'ByVal'");
+                               
+               set_implicit_value_parameter_type = (Expression) yyVals[-1+yyTop];
+               
+               if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
+                       Report.Error (31064, 
+                               lexer.Location, 
+                               "Set value parameter type can not be different from property type");
+                               
+               if (yyVals[-3+yyTop] != null)
+                       set_implicit_value_parameter_name = (string) yyVals[-2+yyTop];
+               else
+                       set_implicit_value_parameter_name = "Value";
+       }
+  break;
+case 227:
+#line 2478 "mb-parser.jay"
+  {              
+               int mod = (int) current_modifiers;
+
+               VariableDeclaration.FixupTypes ((ArrayList) yyVals[-1+yyTop]);
+               VariableDeclaration.FixupArrayTypes ((ArrayList) yyVals[-1+yyTop]);
+               
+/*             if (current_container is Module)*/
+/*                     mod = mod | Modifiers.STATIC;*/
+                       
+               /* Structure members are Public by default                      */
+               if ((current_container is Struct) && (mod == 0))
+                       mod = Modifiers.PUBLIC;                 
+               
+               if ((mod & Modifiers.Accessibility) == 0)
+                       mod |= Modifiers.PRIVATE;
+                                       
+               foreach (VariableDeclaration var in (ArrayList) yyVals[-1+yyTop]){
+                       Location l = var.Location;
+                       Field field = new Field (current_class, var.type, mod, 
+                                                var.identifier, var.expression_or_array_initializer, 
+                                                (Attributes) null, l);
+
+                       current_container.AddField (field);
+               }
+         }
+  break;
+case 230:
+#line 2555 "mb-parser.jay"
+  {
+               Location l = lexer.Location;
+               MemberName name = MakeName (new MemberName ((string) yyVals[-4+yyTop]));
+
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
+               Delegate del = new Delegate (current_namespace, current_container, TypeManager.system_void_expr,
+                                            current_modifiers, name, (Parameters) yyVals[-2+yyTop], current_attributes, l);
+
+               current_container.AddDelegate (del);
+               RootContext.Tree.RecordDecl (name.GetName (true), del);
+         }
+  break;
+case 231:
+#line 2573 "mb-parser.jay"
+  {
+               Location l = lexer.Location;
+               MemberName name = MakeName (new MemberName ((string) yyVals[-5+yyTop]));
+
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
+               Expression rettype = (yyVals[-1+yyTop] == null) ? TypeManager.system_object_expr : (Expression) yyVals[-1+yyTop];
+               Delegate del = new Delegate (current_namespace, current_container, rettype,
+                                            current_modifiers, name, (Parameters) yyVals[-3+yyTop], current_attributes, l);
+
+               current_container.AddDelegate (del);
+               RootContext.Tree.RecordDecl (name.GetName (true), del);
+         }
+  break;
+case 232:
+#line 2592 "mb-parser.jay"
+  {    yyVal = null; }
+  break;
+case 233:
+#line 2619 "mb-parser.jay"
+  {
+               current_local_parameters = (Parameters) yyVals[-1+yyTop];
+               yyVal = new Constructor (current_class, current_container.Basename, 0, (Parameters) yyVals[-1+yyTop], 
+                                     (ConstructorInitializer) null, lexer.Location);
+         }
+  break;
+case 234:
+#line 2627 "mb-parser.jay"
+  { 
+               Constructor c = (Constructor) yyVals[-3+yyTop];
+               c.Block = (ToplevelBlock) yyVals[0+yyTop];
+               c.ModFlags = (int) current_modifiers;
+               c.OptAttributes = current_attributes;
+
+               /* FIXME: Some more error checking from mcs needs to be merged here ???*/
+               
+               c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
+
+               current_container.AddConstructor(c);
+               current_local_parameters = null;
+         }
+  break;
+case 236:
+#line 2645 "mb-parser.jay"
+  { 
+               yyVal = Parameters.EmptyReadOnlyParameters; 
+         }
+  break;
+case 237:
+#line 2649 "mb-parser.jay"
+  { 
+               yyVal = yyVals[0+yyTop];        
+         }
+  break;
+case 238:
+#line 2656 "mb-parser.jay"
+  { 
+               ArrayList pars_list = (ArrayList) yyVals[0+yyTop];
+               Parameter [] pars = null; 
+               Parameter array_parameter = null;
+               int non_array_count = pars_list.Count;
+               if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
+                       array_parameter = (Parameter) pars_list [pars_list.Count - 1];
+                       non_array_count = pars_list.Count - 1;
+               }
+               foreach (Parameter par in pars_list)
+                       if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
+                               Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
+                               non_array_count = 0; 
+                               array_parameter = null;
+                               break;
+                       }
+               if (non_array_count > 0) {
+                       pars = new Parameter [non_array_count];
+                       pars_list.CopyTo (0, pars, 0, non_array_count);
+               }
+               yyVal = new Parameters (pars, array_parameter, lexer.Location); 
+         }
+  break;
+case 239:
+#line 2682 "mb-parser.jay"
+  {
+               ArrayList pars = new ArrayList ();
+
+               pars.Add (yyVals[0+yyTop]);
+               yyVal = pars;
+         }
+  break;
+case 240:
+#line 2689 "mb-parser.jay"
+  {
+               ArrayList pars = (ArrayList) yyVals[-2+yyTop];
+
+               pars.Add (yyVals[0+yyTop]);
+               yyVal = yyVals[-2+yyTop];
+         }
+  break;
+case 241:
+#line 2701 "mb-parser.jay"
+  {
+               Parameter.Modifier pm = (Parameter.Modifier)yyVals[-5+yyTop];
+               bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
+               Expression ptype;
+               
+               if (opt_parm && (yyVals[0+yyTop] == null))
+                       Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
+
+               if (!opt_parm && (yyVals[0+yyTop] != null))
+                       Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
+
+               if ((pm & Parameter.Modifier.PARAMS) != 0) {
+                       if ((pm & ~Parameter.Modifier.PARAMS) != 0)
+                               Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
+               }
+               
+               if ((pm & Parameter.Modifier.REF) !=0)
+                       pm |= Parameter.Modifier.ISBYREF;
+               
+               if (yyVals[-3+yyTop] != null && yyVals[-1+yyTop] != null && yyVals[-3+yyTop] != yyVals[-1+yyTop])
+                       Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); /* TODO: Correct error number and message text*/
+
+               ptype = (Expression)((yyVals[-1+yyTop] == null) ? ((yyVals[-3+yyTop] == null) ? TypeManager.system_object_expr : yyVals[-3+yyTop]) : yyVals[-1+yyTop]);
+               if (yyVals[-2+yyTop] != null)   {
+                       string t = ptype.ToString ();
+                       if (t.IndexOf('[') >= 0)
+                               Report.Error (31087, lexer.Location, "Array types specified in too many places");
+                       else    
+                               ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) yyVals[-2+yyTop], true, lexer.Location), lexer.Location);
+               }
+               if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
+                       Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
+               yyVal = new Parameter (ptype, (string) yyVals[-4+yyTop], pm,
+                                       (Attributes) yyVals[-6+yyTop], (Expression) yyVals[0+yyTop], opt_parm);
+         }
+  break;
+case 242:
+#line 2739 "mb-parser.jay"
+  { yyVal = Parameter.Modifier.VAL;    }
+  break;
+case 243:
+#line 2740 "mb-parser.jay"
+  { yyVal = yyVals[0+yyTop];                   }
+  break;
+case 244:
+#line 2744 "mb-parser.jay"
+  { yyVal = (Parameter.Modifier)yyVals[-1+yyTop] | (Parameter.Modifier)yyVals[0+yyTop];        }
+  break;
+case 245:
+#line 2745 "mb-parser.jay"
+  { yyVal = yyVals[0+yyTop];   }
+  break;
+case 246:
+#line 2749 "mb-parser.jay"
+  { yyVal = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
+  break;
+case 247:
+#line 2750 "mb-parser.jay"
+  { yyVal = Parameter.Modifier.VAL; }
+  break;
+case 248:
+#line 2751 "mb-parser.jay"
+  { yyVal = Parameter.Modifier.OPTIONAL; }
+  break;
+case 249:
+#line 2752 "mb-parser.jay"
+  { yyVal = Parameter.Modifier.PARAMS; }
+  break;
+case 254:
+#line 2768 "mb-parser.jay"
+  { yyVal = yyVals[0+yyTop]; }
+  break;
+case 255:
+#line 2773 "mb-parser.jay"
+  {
+                 if (current_block == null){
+                         current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, lexer.Location);
+                         top_current_block = current_block;
+                 } else {
+                 current_block = new Block (current_block, current_local_parameters,
+                                                lexer.Location, Location.Null);
+                 }
+       }
+  break;
+case 256:
+#line 2787 "mb-parser.jay"
+  { 
+               while (current_block.Implicit)
+                       current_block = current_block.Parent;
+               yyVal = current_block;
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+               if (current_block == null)
+                       top_current_block = null;
+         }
+  break;
+case 257:
+#line 2800 "mb-parser.jay"
+  {
+                 if (yyVals[0+yyTop] != null && (Block) yyVals[0+yyTop] != current_block){
+                       current_block.AddStatement ((Statement) yyVals[0+yyTop]);
+                       current_block = (Block) yyVals[0+yyTop];
+                 }
+           }
+  break;
+case 258:
+#line 2807 "mb-parser.jay"
+  {
+                 Statement s = (Statement) yyVals[0+yyTop];
+
+                 current_block.AddStatement ((Statement) yyVals[0+yyTop]);
+           }
+  break;
+case 259:
+#line 2814 "mb-parser.jay"
+  {
+               Location loc = lexer.Location;
+
+               ExpressionStatement expr = new CompoundAssign (Binary.Operator.Addition, 
+                                        (Expression) yyVals[-3+yyTop], (Expression) yyVals[0+yyTop], loc);
+
+               Statement stmt = new StatementExpression (expr, loc); 
+
+               current_block.AddStatement (stmt);
+
+           }
+  break;
+case 260:
+#line 2827 "mb-parser.jay"
+  {
+               Location loc = lexer.Location;
+
+               ExpressionStatement expr = new CompoundAssign (Binary.Operator.Subtraction, 
+                                        (Expression) yyVals[-3+yyTop], (Expression) yyVals[0+yyTop], loc);
+
+               Statement stmt = new StatementExpression (expr, loc); 
+
+               current_block.AddStatement (stmt);
+
+           }
+  break;
+case 261:
+#line 2839 "mb-parser.jay"
+  {
+             Location loc = lexer.Location;
+             MemberName mname = new MemberName ((string) yyVals[-1+yyTop]);
+             Expression expr = mname.GetTypeExpression (loc);
+
+             Invocation inv_expr = new Invocation (expr, (ArrayList) yyVals[0+yyTop], loc);
+             Statement stmt = new StatementExpression (inv_expr, loc); 
+             current_block.AddStatement (stmt);        
+           }
+  break;
+case 262:
+#line 2860 "mb-parser.jay"
+  { yyVal = null; }
+  break;
+case 263:
+#line 2862 "mb-parser.jay"
+  {
+               yyVal = yyVals[-1+yyTop];
+         }
+  break;
+case 272:
+#line 3027 "mb-parser.jay"
+  {
+               yyVal = new Goto (current_block, (string) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 273:
+#line 3034 "mb-parser.jay"
+  {
+               yyVal = new Throw ((Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 274:
+#line 3059 "mb-parser.jay"
+  {      
+               yyVal = new Return ((Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 275:
+#line 3185 "mb-parser.jay"
+  {
+               yyVal = new Lock ((Expression) yyVals[-4+yyTop], (Statement) yyVals[-2+yyTop], lexer.Location);
+         }
+  break;
+case 278:
+#line 3198 "mb-parser.jay"
+  {
+               Catch g = null;
+               
+               ArrayList c = (ArrayList)yyVals[-2+yyTop];
+               for (int i = 0; i < c.Count; ++i) {
+                       Catch cc = (Catch) c [i];
+                       if (cc.IsGeneral) {
+                               if (i != c.Count - 1)
+                                       Report.Error (1017, cc.loc, "Empty catch block must be the last in a series of catch blocks");
+                               g = cc;
+                               c.RemoveAt (i);
+                               i--;
+                       }
+               }
+
+               /* Now s contains the list of specific catch clauses*/
+               /* and g contains the general one.*/
+               
+               yyVal = new Try ((Block) yyVals[-3+yyTop], c, g, null, ((Block) yyVals[-3+yyTop]).loc);
+         }
+  break;
+case 279:
+#line 3227 "mb-parser.jay"
+  {
+               Catch g = null;
+               ArrayList s = new ArrayList (4);
+               ArrayList catch_list = (ArrayList) yyVals[-5+yyTop];
+
+               if (catch_list != null){
+                       foreach (Catch cc in catch_list) {
+                               if (cc.IsGeneral)
+                                       g = cc;
+                               else
+                                       s.Add (cc);
+                       }
+               }
+
+               yyVal = new Try ((Block) yyVals[-6+yyTop], s, g, (Block) yyVals[-2+yyTop], ((Block) yyVals[-6+yyTop]).loc);
+         }
+  break;
+case 280:
+#line 3246 "mb-parser.jay"
+  {  yyVal = null;  }
+  break;
+case 282:
+#line 3252 "mb-parser.jay"
+  {
+               ArrayList l = new ArrayList (4);
+
+               l.Add (yyVals[0+yyTop]);
+               yyVal = l;
+         }
+  break;
+case 283:
+#line 3259 "mb-parser.jay"
+  {
+               ArrayList l = (ArrayList) yyVals[-1+yyTop];
+
+               l.Add (yyVals[0+yyTop]);
+               yyVal = l;
+         }
+  break;
+case 284:
+#line 3268 "mb-parser.jay"
+  {  yyVal = null;  }
+  break;
+case 286:
+#line 3281 "mb-parser.jay"
+  {
+               /* FIXME: opt_when needs to be hnadled*/
+               Expression type = null;
+               string id = null;
+               
+               if (yyVals[-1+yyTop] != null) {
+                       DictionaryEntry cc = (DictionaryEntry) yyVals[-1+yyTop];
+                       type = (Expression) cc.Key;
+                       id   = (string) cc.Value;
+
+                       if (id != null){
+                               ArrayList one = new ArrayList (4);
+                               Location loc = lexer.Location;
+
+                               one.Add (new VariableDeclaration (id, type, loc));
+
+                               yyVals[-2+yyTop] = current_block;
+                               current_block = new Block (current_block);
+                               Block b = declare_local_variables (type, one, loc);
+                               current_block = b;
+                       }
+               }
+       }
+  break;
+case 287:
+#line 3305 "mb-parser.jay"
+  {
+               Expression type = null;
+               string id = null;
+
+               if (yyVals[-3+yyTop] != null){
+                       DictionaryEntry cc = (DictionaryEntry) yyVals[-3+yyTop];
+                       type = (Expression) cc.Key;
+                       id   = (string) cc.Value;
+
+                       if (yyVals[-4+yyTop] != null){
+                               /**/
+                               /* FIXME: I can change this for an assignment.*/
+                               /**/
+                               while (current_block != (Block) yyVals[-4+yyTop])
+                                       current_block = current_block.Parent;
+                       }
+               }
+
+
+               yyVal = new Catch (type, id , (Block) yyVals[0+yyTop], ((Block) yyVals[0+yyTop]).loc);
+       }
+  break;
+case 288:
+#line 3329 "mb-parser.jay"
+  {  yyVal = null; }
+  break;
+case 290:
+#line 3335 "mb-parser.jay"
+  {
+                yyVal = new DictionaryEntry (yyVals[0+yyTop], yyVals[-2+yyTop]); 
+       }
+  break;
+case 291:
+#line 3388 "mb-parser.jay"
+  {
+               oob_stack.Push (lexer.Location);
+       }
+  break;
+case 292:
+#line 3396 "mb-parser.jay"
+  {
+               Location l = (Location) oob_stack.Pop ();
+               yyVal = new While ((Expression) yyVals[-6+yyTop], (Statement) yyVals[-2+yyTop], l);
+       }
+  break;
+case 294:
+#line 3471 "mb-parser.jay"
+  { 
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               yyVal = new If ((Expression) yyVals[-5+yyTop], (Statement) yyVals[-2+yyTop], l);
+
+               if (RootContext.WarningLevel >= 3){
+                       if (yyVals[-2+yyTop] == EmptyStatement.Value)
+                               Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
+               }
+
+         }
+  break;
+case 295:
+#line 3489 "mb-parser.jay"
+  {
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               yyVal = new If ((Expression) yyVals[-8+yyTop], (Statement) yyVals[-5+yyTop], (Statement) yyVals[-2+yyTop], l);
+         }
+  break;
+case 296:
+#line 3499 "mb-parser.jay"
+  {
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               yyVal = new If ((Expression) yyVals[-4+yyTop], (Statement) yyVals[-1+yyTop], (Statement) yyVals[0+yyTop], l);
+         }
+  break;
+case 297:
+#line 3511 "mb-parser.jay"
+  { 
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               yyVal = new If ((Expression) yyVals[-5+yyTop], (Statement) yyVals[-2+yyTop], l);
+
+               if (RootContext.WarningLevel >= 3){
+                       if (yyVals[-2+yyTop] == EmptyStatement.Value)
+                               Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
+               }
+
+         }
+  break;
+case 298:
+#line 3529 "mb-parser.jay"
+  {
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               yyVal = new If ((Expression) yyVals[-8+yyTop], (Statement) yyVals[-5+yyTop], (Statement) yyVals[-2+yyTop], l);
+         }
+  break;
+case 299:
+#line 3539 "mb-parser.jay"
+  {
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               yyVal = new If ((Expression) yyVals[-4+yyTop], (Statement) yyVals[-1+yyTop], (Statement) yyVals[0+yyTop], l);
+         }
+  break;
+case 302:
+#line 3667 "mb-parser.jay"
+  {
+               ArrayList labels = new ArrayList ();
+
+               labels.Add (yyVals[0+yyTop]);
+               yyVal = labels;
+         }
+  break;
+case 303:
+#line 3674 "mb-parser.jay"
+  {
+               ArrayList labels = (ArrayList) (yyVals[-2+yyTop]);
+               labels.Add (yyVals[-1+yyTop]);
+
+               yyVal = labels;
+         }
+  break;
+case 305:
+#line 3685 "mb-parser.jay"
+  {
+               yyVal = new SwitchLabel ((Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 314:
+#line 3710 "mb-parser.jay"
+  {
+                yyVal = yyVals[0+yyTop]; 
+         }
+  break;
+case 315:
+#line 3717 "mb-parser.jay"
+  { yyVal = new StatementExpression ((ExpressionStatement) yyVals[0+yyTop], lexer.Location);  }
+  break;
+case 316:
+#line 3718 "mb-parser.jay"
+  { yyVal = new StatementExpression ((ExpressionStatement) yyVals[0+yyTop], lexer.Location);  }
+  break;
+case 317:
+#line 3719 "mb-parser.jay"
+  { yyVal = new StatementExpression ((ExpressionStatement) yyVals[0+yyTop], lexer.Location);  }
+  break;
+case 318:
+#line 3724 "mb-parser.jay"
+  {
+               yyVal = new New ((Expression) yyVals[-3+yyTop], (ArrayList) yyVals[-1+yyTop], lexer.Location);
+         }
+  break;
+case 319:
+#line 3728 "mb-parser.jay"
+  {
+               yyVal = new New ((Expression) yyVals[0+yyTop], new ArrayList(), lexer.Location);
+         }
+  break;
+case 321:
+#line 3775 "mb-parser.jay"
+  {
+               if (yyVals[0+yyTop] != null){
+                       DictionaryEntry de = (DictionaryEntry) yyVals[0+yyTop];
+
+                       yyVal = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
+               }
+         }
+  break;
+case 322:
+#line 3783 "mb-parser.jay"
+  {
+               if (yyVals[0+yyTop] != null){
+                       DictionaryEntry de = (DictionaryEntry) yyVals[0+yyTop];
+
+                       yyVal = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
+               }
+         }
+  break;
+case 323:
+#line 3794 "mb-parser.jay"
+  {
+               yyVal = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), yyVals[0+yyTop]);             
+         }
+  break;
+case 324:
+#line 3802 "mb-parser.jay"
+  {
+               if (yyVals[0+yyTop] != null)
+                       yyVal = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), yyVals[0+yyTop]);
+               else
+                       yyVal = null;
+         }
+  break;
+case 325:
+#line 3812 "mb-parser.jay"
+  {
+               ArrayList decl = new ArrayList ();
+               if (yyVals[0+yyTop] != null) 
+                       decl.Add (yyVals[0+yyTop]);
+                       
+               yyVal = decl;
+         }
+  break;
+case 326:
+#line 3820 "mb-parser.jay"
+  {
+               ArrayList decls = (ArrayList) yyVals[-2+yyTop];
+               if (yyVals[0+yyTop] != null)
+                       decls.Add (yyVals[0+yyTop]);
+
+               yyVal = yyVals[-2+yyTop];
+         }
+  break;
+case 327:
+#line 3831 "mb-parser.jay"
+  {
+               VarName vname = (VarName) yyVals[-2+yyTop];
+               string varname = (string) vname.Name;
+               current_rank_specifiers = (ArrayList) vname.Rank;
+               object varinit = yyVals[0+yyTop];
+               ArrayList a_dims = null;
+
+               if (varinit == null)
+                       Report.Error (
+                               30438, lexer.Location, "Constant should have a value"
+                               );
+
+               if (vname.Type != null && yyVals[-1+yyTop] != null)
+                       Report.Error (
+                               30302, lexer.Location, 
+                               "Type character cannot be used with explicit type declaration" );
+
+               Expression vartype = (yyVals[-1+yyTop] == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) yyVals[-1+yyTop];
+
+               if (current_rank_specifiers != null) 
+               {
+                       Report.Error (30424, lexer.Location, "Constant doesn't support array");
+                       yyVal = null;
+               }
+               else
+                       yyVal = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
+         }
+  break;
+case 328:
+#line 3862 "mb-parser.jay"
+  {
+               ArrayList decl = new ArrayList ();
+               decl.AddRange ((ArrayList) yyVals[0+yyTop]);
+               yyVal = decl;
+         }
+  break;
+case 329:
+#line 3868 "mb-parser.jay"
+  {
+               ArrayList decls = (ArrayList) yyVals[-2+yyTop];
+               decls.AddRange ((ArrayList) yyVals[0+yyTop]);
+               yyVal = yyVals[-2+yyTop];
+         }
+  break;
+case 330:
+#line 3877 "mb-parser.jay"
+  {
+           ArrayList names = (ArrayList) yyVals[-2+yyTop];
+               object varinit = yyVals[0+yyTop];
+               ArrayList VarDeclarations = new ArrayList();
+               Expression vartype;
+               ArrayList a_dims = null;
+
+               if ((names.Count > 1) && (varinit != null)) 
+                       Report.Error (
+                               30671, lexer.Location, 
+                               "Multiple variables with single type can not have " +
+                               "a explicit initialization" );
+
+                               
+               foreach (VarName vname in names)
+               {
+                       string varname = (string) vname.Name;
+                       current_rank_specifiers = (ArrayList) vname.Rank;
+                       a_dims = null;
+                       varinit = yyVals[0+yyTop];
+
+                       if(vname.Type != null && yyVals[-1+yyTop] != null)
+                               Report.Error (
+                                       30302, lexer.Location, 
+                                       "Type character cannot be used with explicit type declaration" );
+
+                       /* Some checking is required for particularly weird declarations*/
+                       /* like Dim a As Integer(,)*/
+                       if (yyVals[-1+yyTop] is Pair) {
+                               vartype = (Expression) ((Pair) yyVals[-1+yyTop]).First;
+                               
+                               /*if ($3 != null && $3 is ArrayList)
+                                       Report.Error (205, "End of statement expected.");*/
+                                       
+                               ArrayList args = (ArrayList) ((Pair) yyVals[-1+yyTop]).Second;
+                               if (current_rank_specifiers != null)
+                                       Report.Error (31087, lexer.Location,
+                                                "Array types specified in too many places");   
+                               
+                               if (VariableDeclaration.IndexesSpecifiedInRank (args))            
+                                       Report.Error (30638, "Array bounds cannot appear in type specifiers."); 
+                               
+                               current_rank_specifiers = new ArrayList ();
+                               current_rank_specifiers.Add (args);                             
+                       }
+                       else
+                               vartype = (yyVals[-1+yyTop] == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) yyVals[-1+yyTop];
+
+                       /* if the variable is an array with explicit bound*/
+                       /* and having explicit initialization throw exception*/
+                       if (current_rank_specifiers != null && varinit != null) 
+                       {
+                               bool broken = false;
+                               foreach (ArrayList exprs in current_rank_specifiers)
+                               {
+                                       foreach (Expression expr in exprs)
+                                       {
+                                               if (!((Expression)expr is EmptyExpression ))
+                                               {
+                                                       Report.Error (
+                                                               30672, lexer.Location, 
+                                                               "Array declared with explicit bound " +
+                                                               " can not have explicit initialization");
+                                                       broken = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (broken)
+                                               break;
+                               }
+                       }
+                       
+                       /*
+                       Check for a declaration like Dim a(2) or Dim a(2,3)
+                       If this is the case, we must generate an ArrayCreationExpression
+                       and, in case, add the initializer after the array has been created.
+                       */
+/*                     if (VariableDeclaration.IsArrayDecl (this)) {   */
+/*                             if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {   */
+/*                                     a_dims = (ArrayList) current_rank_specifiers;*/
+/*                                     VariableDeclaration.VBFixIndexLists (ref a_dims);*/
+/*                                     varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);*/
+/*                             }*/
+/*                             vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);*/
+/*                     }*/
+
+                       if (vartype is New) {
+                               if (varinit != null) {
+                                       Report.Error (30205, lexer.Location, "End of statement expected");
+                                       yyVal = null;
+                               }
+                               else
+                               {
+                                       varinit = vartype;
+                                       vartype = ((New)vartype).RequestedType;
+                               }
+                       }
+                       VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
+           }/* end of for*/
+           yyVal = VarDeclarations;
+         }
+  break;
+case 331:
+#line 3982 "mb-parser.jay"
+  {
+               ArrayList list = new ArrayList ();
+               list.Add (yyVals[0+yyTop]);
+               yyVal = list;
+         }
+  break;
+case 332:
+#line 3988 "mb-parser.jay"
+  {
+               ArrayList list = (ArrayList) yyVals[-2+yyTop];
+               list.Add (yyVals[0+yyTop]);
+               yyVal = list;
+         }
+  break;
+case 333:
+#line 3997 "mb-parser.jay"
+  {
+               yyVal = new VarName (yyVals[-2+yyTop], yyVals[-1+yyTop], yyVals[0+yyTop]);
+         }
+  break;
+case 334:
+#line 4004 "mb-parser.jay"
+  { 
+               yyVal = null;           
+         }
+  break;
+case 335:
+#line 4008 "mb-parser.jay"
+  { 
+               yyVal = (Expression) yyVals[0+yyTop];
+         }
+  break;
+case 337:
+#line 4023 "mb-parser.jay"
+  {
+               yyVal = yyVals[0+yyTop];
+         }
+  break;
+case 338:
+#line 4027 "mb-parser.jay"
+  {
+               New n = new New ((Expression)yyVals[0+yyTop], null, lexer.Location);
+               yyVal = (Expression) n;
+         }
+  break;
+case 339:
+#line 4032 "mb-parser.jay"
+  {
+               New n = new New ((Expression)yyVals[-3+yyTop], (ArrayList) yyVals[-1+yyTop], lexer.Location);
+               yyVal = (Expression) n;
+         }
+  break;
+case 340:
+#line 4048 "mb-parser.jay"
+  { yyVal = null; }
+  break;
+case 341:
+#line 4057 "mb-parser.jay"
+  { yyVal = null; }
+  break;
+case 342:
+#line 4058 "mb-parser.jay"
+  { yyVal = yyVals[0+yyTop]; }
+  break;
+case 343:
+#line 4063 "mb-parser.jay"
+  {
+               yyVal = yyVals[0+yyTop];
+         }
+  break;
+case 344:
+#line 4067 "mb-parser.jay"
+  {
+               yyVal = yyVals[0+yyTop];
+         }
+  break;
+case 345:
+#line 4075 "mb-parser.jay"
+  {
+               ArrayList list = new ArrayList ();
+               yyVal = list;
+         }
+  break;
+case 346:
+#line 4080 "mb-parser.jay"
+  {
+               yyVal = (ArrayList) yyVals[-1+yyTop];
+         }
+  break;
+case 347:
+#line 4087 "mb-parser.jay"
+  {
+               ArrayList list = new ArrayList ();
+               list.Add (yyVals[0+yyTop]);
+               yyVal = list;
+         }
+  break;
+case 348:
+#line 4093 "mb-parser.jay"
+  {
+               ArrayList list = (ArrayList) yyVals[-2+yyTop];
+               list.Add (yyVals[0+yyTop]);
+               yyVal = list;
+         }
+  break;
+case 349:
+#line 4102 "mb-parser.jay"
+  {
+                 /* $$ = "";*/
+                 yyVal = null;
+         }
+  break;
+case 350:
+#line 4107 "mb-parser.jay"
+  {
+                       yyVal = yyVals[0+yyTop];
+         }
+  break;
+case 351:
+#line 4114 "mb-parser.jay"
+  {
+                 ArrayList rs = new ArrayList();
+                 rs.Add (yyVals[0+yyTop]);
+                 yyVal = rs;
+         }
+  break;
+case 352:
+#line 4120 "mb-parser.jay"
+  {
+                 ArrayList rs = (ArrayList) yyVals[-1+yyTop];
+                 rs.Add (yyVals[0+yyTop]);
+                 yyVal = rs;
+         }
+  break;
+case 353:
+#line 4129 "mb-parser.jay"
+  {
+               yyVal = yyVals[-1+yyTop];
+         }
+  break;
+case 354:
+#line 4136 "mb-parser.jay"
+  {
+               ArrayList ds = new ArrayList();
+               ds.Add (new EmptyExpression());
+               yyVal = ds;
+         }
+  break;
+case 355:
+#line 4142 "mb-parser.jay"
+  {
+               ArrayList ds = new ArrayList();
+               ds.Add ((Expression) yyVals[0+yyTop]);
+               yyVal = ds;
+         }
+  break;
+case 356:
+#line 4148 "mb-parser.jay"
+  {
+               ArrayList ds = (ArrayList) yyVals[-2+yyTop];
+               ds.Add ((Expression) yyVals[0+yyTop]);
+               yyVal = ds;             
+         }
+  break;
+case 357:
+#line 4154 "mb-parser.jay"
+  {
+               ArrayList ds = (ArrayList) yyVals[-1+yyTop];
+               ds.Add (new EmptyExpression());
+               yyVal = ds;             
+         }
+  break;
+case 358:
+#line 4184 "mb-parser.jay"
+  {
+               /*TODO*/
+         }
+  break;
+case 362:
+#line 4191 "mb-parser.jay"
+  {
+               yyVal = ((MemberName) yyVals[0+yyTop]).GetTypeExpression (lexer.Location);
+         }
+  break;
+case 371:
+#line 4209 "mb-parser.jay"
+  { yyVal = new CharLiteral ((char) lexer.Value); }
+  break;
+case 372:
+#line 4210 "mb-parser.jay"
+  { yyVal = new StringLiteral ((string) lexer.Value); }
+  break;
+case 373:
+#line 4211 "mb-parser.jay"
+  { yyVal = NullLiteral.Null; }
+  break;
+case 374:
+#line 4215 "mb-parser.jay"
+  { yyVal = new FloatLiteral ((float) lexer.Value); }
+  break;
+case 375:
+#line 4216 "mb-parser.jay"
+  { yyVal = new DoubleLiteral ((double) lexer.Value); }
+  break;
+case 376:
+#line 4217 "mb-parser.jay"
+  { yyVal = new DecimalLiteral ((decimal) lexer.Value); }
+  break;
+case 377:
+#line 4221 "mb-parser.jay"
+  {
+               object v = lexer.Value;
+
+               if (v is int)
+                       yyVal = new IntLiteral ((Int32)v); 
+/*             else if (v is short)*/
+/*                     $$ = new ShortLiteral ((Int16)v);*/
+               else if (v is long)
+                       yyVal = new LongLiteral ((Int64)v);
+               else
+                       Console.WriteLine ("OOPS.  Unexpected result from scanner");
+                       
+         }
+  break;
+case 378:
+#line 4237 "mb-parser.jay"
+  { yyVal = new BoolLiteral (true); }
+  break;
+case 379:
+#line 4238 "mb-parser.jay"
+  { yyVal = new BoolLiteral (false); }
+  break;
+case 380:
+#line 4243 "mb-parser.jay"
+  { yyVal = yyVals[-1+yyTop]; }
+  break;
+case 381:
+#line 4248 "mb-parser.jay"
+  {
+               if (yyVals[-2+yyTop] != null) {
+                       string id_name = (string)yyVals[0+yyTop];
+                       if (id_name.ToUpper() == "NEW")
+                               id_name = ".ctor";
+                       yyVal = new MemberAccess ((Expression) yyVals[-2+yyTop], id_name, lexer.Location);
+               }
+               else
+               {
+/*                     if (with_stack.Count > 0) {*/
+/*                             Expression e = (Expression) with_stack.Peek();*/
+/*                             $$ = new MemberAccess (e, (string) $3, lexer.Location);*/
+/*                     }*/
+/*                     else*/
+/*                     {*/
+/*                             // OOps*/
+/*                     }*/
+               }
+         }
+  break;
+case 382:
+#line 4272 "mb-parser.jay"
+  {
+               if (yyVals[-2+yyTop] != null)
+                       yyVal = new MemberAccess ((Expression) yyVals[-2+yyTop], (string) yyVals[0+yyTop], lexer.Location);
+               else
+               {
+/*                     if (with_stack.Count > 0) {*/
+/*                             Expression e = (Expression) with_stack.Peek();*/
+/*                             $$ = new MemberAccess (e, (string) $3, lexer.Location);*/
+/*                     }*/
+/*                     else*/
+/*                     {*/
+/*                             // OOps*/
+/*                     }*/
+               }
+         }
+  break;
+case 384:
+#line 4295 "mb-parser.jay"
+  {
+               if (yyVals[-3+yyTop] == null) {
+                       Location l = lexer.Location;
+                       Report.Error (1, l, "Parse error");
+               }
+               yyVal = new Invocation ((Expression) yyVals[-3+yyTop], (ArrayList) yyVals[-1+yyTop], lexer.Location);
+         }
+  break;
+case 385:
+#line 4303 "mb-parser.jay"
+  {
+               if (yyVals[-3+yyTop] == null) {
+                       Location l = lexer.Location;
+                       Report.Error (1, l, "THIS IS CRAZY");
+               }
+               yyVal = new Invocation ((Expression) yyVals[-3+yyTop], (ArrayList) yyVals[-2+yyTop], lexer.Location);
+/*             Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);*/
+         }
+  break;
+case 386:
+#line 4315 "mb-parser.jay"
+  {
+               string id_name = (string) yyVals[0+yyTop];
+               if (id_name.ToUpper() == "NEW")
+                       id_name = "New";
+               yyVal = new BaseAccess (id_name, lexer.Location);
+         }
+  break;
+case 387:
+#line 4329 "mb-parser.jay"
+  { 
+               /*
+                  The 'argument' rule returns an 'empty' argument
+                  of type NoArg (used for default arguments in invocations)
+                  if no arguments are actually passed.
+
+                  If there is only one argument and it is o type NoArg,
+                  we return a null (empty) list
+               */
+               ArrayList args = (ArrayList) yyVals[0+yyTop];
+               if (args.Count == 1 &&
+                   ((Argument)args[0]).ArgType == Argument.AType.NoArg)
+                       yyVal = null;
+               else
+                       yyVal = yyVals[0+yyTop];
+         }
+  break;
+case 388:
+#line 4349 "mb-parser.jay"
+  {
+               ArrayList list = new ArrayList ();
+               list.Add (yyVals[0+yyTop]);
+               yyVal = list;
+         }
+  break;
+case 389:
+#line 4355 "mb-parser.jay"
+  {
+               ArrayList list = (ArrayList) yyVals[-2+yyTop];
+               list.Add (yyVals[0+yyTop]);
+               yyVal = list;
+         }
+  break;
+case 390:
+#line 4364 "mb-parser.jay"
+  {
+               yyVal = new Argument ((Expression) yyVals[0+yyTop], Argument.AType.Expression);
+         }
+  break;
+case 391:
+#line 4368 "mb-parser.jay"
+  {
+               yyVal = new Argument ((Expression) yyVals[0+yyTop], Argument.AType.Ref);
+         }
+  break;
+case 392:
+#line 4372 "mb-parser.jay"
+  {
+               yyVal = new Argument (new EmptyExpression (), Argument.AType.NoArg);
+         }
+  break;
+case 393:
+#line 4376 "mb-parser.jay"
+  {
+               yyVal = new Argument ((Expression) yyVals[0+yyTop], Argument.AType.AddressOf);
+         }
+  break;
+case 394:
+#line 4382 "mb-parser.jay"
+  {/* note ("section 5.4"); */  yyVal = yyVals[0+yyTop];  }
+  break;
+case 395:
+#line 4387 "mb-parser.jay"
+  { yyVal = yyVals[0+yyTop]; }
+  break;
+case 398:
+#line 4398 "mb-parser.jay"
+  {
+               yyVal = new This (current_block, lexer.Location);
+         }
+  break;
+case 399:
+#line 4402 "mb-parser.jay"
+  {
+               /* FIXME: This is actually somewhat different from Me*/
+               /* because it is for accessing static (classifier) methods/properties/fields*/
+               yyVal = new This (current_block, lexer.Location);
+         }
+  break;
+case 400:
+#line 4411 "mb-parser.jay"
+  {
+               /* TODO*/
+         }
+  break;
+case 401:
+#line 4415 "mb-parser.jay"
+  {
+                 yyVal = new Cast ((Expression) yyVals[-1+yyTop], (Expression) yyVals[-3+yyTop], lexer.Location);
+         }
+  break;
+case 402:
+#line 4419 "mb-parser.jay"
+  {
+                 yyVal = new Cast ((Expression) yyVals[-3+yyTop], (Expression) yyVals[-1+yyTop], lexer.Location);
+         }
+  break;
+case 403:
+#line 4425 "mb-parser.jay"
+  { yyVal = TypeManager.system_boolean_expr;   }
+  break;
+case 404:
+#line 4426 "mb-parser.jay"
+  { yyVal = TypeManager.system_byte_expr;              }
+  break;
+case 405:
+#line 4427 "mb-parser.jay"
+  { yyVal = TypeManager.system_char_expr;              }
+  break;
+case 406:
+#line 4429 "mb-parser.jay"
+  { yyVal = TypeManager.system_double_expr;            }
+  break;
+case 407:
+#line 4430 "mb-parser.jay"
+  { yyVal = TypeManager.system_decimal_expr;   }
+  break;
+case 408:
+#line 4431 "mb-parser.jay"
+  { yyVal = TypeManager.system_int32_expr;             }
+  break;
+case 409:
+#line 4432 "mb-parser.jay"
+  { yyVal = TypeManager.system_int64_expr;             }
+  break;
+case 410:
+#line 4433 "mb-parser.jay"
+  { yyVal = TypeManager.system_object_expr;            }
+  break;
+case 411:
+#line 4434 "mb-parser.jay"
+  { yyVal = TypeManager.system_int16_expr;             }
+  break;
+case 412:
+#line 4435 "mb-parser.jay"
+  { yyVal = TypeManager.system_single_expr;            }
+  break;
+case 413:
+#line 4436 "mb-parser.jay"
+  { yyVal = TypeManager.system_string_expr;    }
+  break;
+case 414:
+#line 4441 "mb-parser.jay"
+  {
+               yyVal = new TypeOf ((Expression) yyVals[-1+yyTop], lexer.Location);
+         }
+  break;
+case 416:
+#line 4449 "mb-parser.jay"
+  {
+               /*TODO*/
+         }
+  break;
+case 418:
+#line 4457 "mb-parser.jay"
+  {
+               /*FIXME: Is this rule correctly defined ?*/
+               yyVal = new Unary (Unary.Operator.UnaryPlus, (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 419:
+#line 4462 "mb-parser.jay"
+  {
+               /*FIXME: Is this rule correctly defined ?*/
+               yyVal = new Unary (Unary.Operator.UnaryNegation, (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 421:
+#line 4471 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.Multiply,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 422:
+#line 4476 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.Division,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 424:
+#line 4485 "mb-parser.jay"
+  {
+               /*FIXME: Is this right ?*/
+               yyVal = new Binary (Binary.Operator.Division,
+                          (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+          }
+  break;
+case 426:
+#line 4495 "mb-parser.jay"
+  {
+             yyVal = new Binary (Binary.Operator.Modulus,
+                              (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 428:
+#line 4504 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.Addition,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 429:
+#line 4509 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.Subtraction,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 431:
+#line 4518 "mb-parser.jay"
+  {
+             /* FIXME: This should only work for String expressions*/
+             /* We probably need to use something from the runtime*/
+             yyVal = new Binary (Binary.Operator.Addition,
+                              (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 433:
+#line 4529 "mb-parser.jay"
+  {
+               /* TODO*/
+         }
+  break;
+case 434:
+#line 4533 "mb-parser.jay"
+  {
+               /*TODO*/
+         }
+  break;
+case 436:
+#line 4541 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.Equality,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 437:
+#line 4546 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.Inequality, 
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 438:
+#line 4551 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.LessThan,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 439:
+#line 4556 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.GreaterThan,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 440:
+#line 4561 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.LessThanOrEqual,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 441:
+#line 4566 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.GreaterThanOrEqual,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 442:
+#line 4571 "mb-parser.jay"
+  {
+               /*FIXME: Should be a different op for reference equality but allows tests to use Is*/
+               yyVal = new Binary (Binary.Operator.Equality,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 443:
+#line 4577 "mb-parser.jay"
+  {
+               /*FIXME: Is this rule correctly defined ?*/
+               yyVal = new Is ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 445:
+#line 4586 "mb-parser.jay"
+  {
+               /*FIXME: Is this rule correctly defined ?*/
+               yyVal = new Unary (Unary.Operator.LogicalNot, (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 447:
+#line 4595 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.LogicalAnd,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 448:
+#line 4600 "mb-parser.jay"
+  {    /* FIXME: this is likely to be broken*/
+               yyVal = new Binary (Binary.Operator.LogicalAnd,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 450:
+#line 4609 "mb-parser.jay"
+  {
+               yyVal = new Binary (Binary.Operator.LogicalOr,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 451:
+#line 4614 "mb-parser.jay"
+  {    /* FIXME: this is likely to be broken*/
+               yyVal = new Binary (Binary.Operator.LogicalOr,
+                                (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 453:
+#line 4623 "mb-parser.jay"
+  {
+             yyVal = new Binary (Binary.Operator.ExclusiveOr,
+                              (Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+       }
+  break;
+case 454:
+#line 4631 "mb-parser.jay"
+  { 
+               yyVal = new Assign ((Expression) yyVals[-2+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 455:
+#line 4635 "mb-parser.jay"
+  {
+               Location l = lexer.Location;
+
+               yyVal = new CompoundAssign (
+                       Binary.Operator.Multiply, (Expression) yyVals[-3+yyTop], (Expression) yyVals[0+yyTop], l);
+         }
+  break;
+case 456:
+#line 4642 "mb-parser.jay"
+  {
+               Location l = lexer.Location;
+
+               yyVal = new CompoundAssign (
+                       Binary.Operator.Division, (Expression) yyVals[-3+yyTop], (Expression) yyVals[0+yyTop], l);
+         }
+  break;
+case 457:
+#line 4649 "mb-parser.jay"
+  {
+               Location l = lexer.Location;
+
+               yyVal = new CompoundAssign (
+                       Binary.Operator.Addition, (Expression) yyVals[-3+yyTop], (Expression) yyVals[0+yyTop], l);
+         }
+  break;
+case 458:
+#line 4656 "mb-parser.jay"
+  {
+               Location l = lexer.Location;
+
+               yyVal = new CompoundAssign (
+                       Binary.Operator.Subtraction, (Expression) yyVals[-3+yyTop], (Expression) yyVals[0+yyTop], l);
+         }
+  break;
+case 459:
+#line 4663 "mb-parser.jay"
+  {
+               Location l = lexer.Location;
+
+               yyVal = new CompoundAssign (
+                       Binary.Operator.LeftShift, (Expression) yyVals[-3+yyTop], (Expression) yyVals[0+yyTop], l);
+         }
+  break;
+case 460:
+#line 4670 "mb-parser.jay"
+  {
+               Location l = lexer.Location;
+
+               yyVal = new CompoundAssign (
+                       Binary.Operator.RightShift, (Expression) yyVals[-3+yyTop], (Expression) yyVals[0+yyTop], l);
+         }
+  break;
+case 461:
+#line 4677 "mb-parser.jay"
+  {
+               Location l = lexer.Location;
+
+               /* FIXME should be strings only*/
+               yyVal = new CompoundAssign (
+                       Binary.Operator.Addition, (Expression) yyVals[-3+yyTop], (Expression) yyVals[0+yyTop], l);
+         }
+  break;
+case 462:
+#line 4685 "mb-parser.jay"
+  {
+               Location l = lexer.Location;
+
+               /* TODO: $$ = new CompoundAssign (
+                       Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
+         }
+  break;
+case 463:
+#line 4692 "mb-parser.jay"
+  { 
+/*             ArrayList args = new ArrayList();*/
+/*             Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);*/
+/*             args.Add (arg);*/
+               
+/*             New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);*/
+/*             n.isDelegate = true;*/
+               yyVal = new Assign ((Expression) yyVals[-3+yyTop], (Expression) yyVals[0+yyTop], lexer.Location);
+         }
+  break;
+case 466:
+#line 4713 "mb-parser.jay"
+  {    
+               yyVal = ((MemberName) yyVals[0+yyTop]).GetTypeExpression (lexer.Location);
+         }
+  break;
+case 468:
+#line 4722 "mb-parser.jay"
+  {
+               ArrayList types = new ArrayList ();
+
+               types.Add (yyVals[0+yyTop]);
+               yyVal = types;
+         }
+  break;
+case 469:
+#line 4729 "mb-parser.jay"
+  {
+               ArrayList types = (ArrayList) yyVals[-2+yyTop];
+
+               types.Add (yyVals[0+yyTop]);
+               yyVal = types;
+         }
+  break;
+case 471:
+#line 4742 "mb-parser.jay"
+  { yyVal = TypeManager.system_object_expr; }
+  break;
+case 474:
+#line 4748 "mb-parser.jay"
+  { yyVal = TypeManager.system_boolean_expr; }
+  break;
+case 475:
+#line 4750 "mb-parser.jay"
+  { yyVal = TypeManager.system_char_expr; }
+  break;
+case 476:
+#line 4751 "mb-parser.jay"
+  { yyVal = TypeManager.system_string_expr; }
+  break;
+case 479:
+#line 4758 "mb-parser.jay"
+  { yyVal = TypeManager.system_decimal_expr; }
+  break;
+case 481:
+#line 4763 "mb-parser.jay"
+  { yyVal = TypeManager.system_byte_expr; }
+  break;
+case 482:
+#line 4764 "mb-parser.jay"
+  { yyVal = TypeManager.system_int16_expr; }
+  break;
+case 483:
+#line 4765 "mb-parser.jay"
+  { yyVal = TypeManager.system_int32_expr; }
+  break;
+case 484:
+#line 4766 "mb-parser.jay"
+  { yyVal = TypeManager.system_int64_expr; }
+  break;
+case 485:
+#line 4770 "mb-parser.jay"
+  { yyVal = TypeManager.system_single_expr; }
+  break;
+case 486:
+#line 4771 "mb-parser.jay"
+  { yyVal = TypeManager.system_double_expr; }
+  break;
+case 487:
+#line 4776 "mb-parser.jay"
+  { 
+/*             if(tokenizerController.IsAcceptingTokens)*/
+/*             {*/
+/*                     if(in_external_source) */
+/*                             Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");*/
+/*                     else {*/
+/*                             in_external_source = true;*/
+                       
+/*                             lexer.EffectiveSource = (string) $4;*/
+/*                             lexer.EffectiveLine = (int) $6;*/
+/*                     }*/
+/*             }*/
+         }
+  break;
+case 488:
+#line 4790 "mb-parser.jay"
+  {
+               if(tokenizerController.IsAcceptingTokens) 
+               {
+                       string id = (yyVals[-2+yyTop] as string);
+               
+                       if(!(yyVals[-2+yyTop] as string).ToLower().Equals("region"))
+                               Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
+                       else
+                       {
+                               ++in_marked_region;
+                       }
+               }
+         }
+  break;
+case 489:
+#line 4804 "mb-parser.jay"
+  {
+               if(tokenizerController.IsAcceptingTokens)
+               {
+/*                     if( ($3 as string).ToLower().Equals("externalsource")) {*/
+/*                             if(!in_external_source)*/
+/*                                     Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");*/
+/*                             else {*/
+/*                                     in_external_source = false;*/
+/*                                     lexer.EffectiveSource = lexer.Source;*/
+/*                                     lexer.EffectiveLine = lexer.Line;*/
+/*                             }*/
+/*                     }*/
+                       /* else */if((yyVals[-1+yyTop] as string).ToLower().Equals("region")) {
+                               if(in_marked_region > 0)
+                                       --in_marked_region;
+                               else
+                                       Report.Error (30205, lexer.Location, "'#End Region' must be preceded  by a matching '#Region'");
+                       }
+                       else {
+                               Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
+                       }       
+               }
+         }
+  break;
+case 490:
+#line 4828 "mb-parser.jay"
+  {
+               if(tokenizerController.IsAcceptingTokens)
+               {
+                       /*TODO;*/
+               }
+         }
+  break;
+case 491:
+#line 4835 "mb-parser.jay"
+  {
+               IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
+
+               try {
+                       ifElseStateMachine.HandleToken(tok);
+               }
+               catch(ApplicationException) {
+                       throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+               }
+         }
+  break;
+case 492:
+#line 4846 "mb-parser.jay"
+  {
+               HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)yyVals[-2+yyTop]);
+         }
+  break;
+case 493:
+#line 4850 "mb-parser.jay"
+  {
+                     IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
+                     try {
+                             ifElseStateMachine.HandleToken(tok);
+                     }
+                     catch(ApplicationException) {
+                             throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                     }
+         }
+  break;
+case 494:
+#line 4860 "mb-parser.jay"
+  { 
+                 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)yyVals[-2+yyTop]);
+         }
+  break;
+case 495:
+#line 4864 "mb-parser.jay"
+  {
+                   IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
+                   try {
+                           ifElseStateMachine.HandleToken(tok);
+                   }
+                   catch(ApplicationException) {
+                           throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                   }
+         }
+  break;
+case 496:
+#line 4874 "mb-parser.jay"
+  { 
+               HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
+         }
+  break;
+case 497:
+#line 4878 "mb-parser.jay"
+  {
+                 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
+                 try {
+                         ifElseStateMachine.HandleToken(tok);
+                 }
+                 catch(ApplicationException) {
+                         throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                 }
+         }
+  break;
+case 498:
+#line 4888 "mb-parser.jay"
+  { 
+               HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
+         }
+  break;
+case 499:
+#line 4892 "mb-parser.jay"
+  {
+               if(tokenizerController.IsAcceptingTokens)
+                       Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
+               else
+                       Report.Warning (9999, lexer.Location,   "Unrecognized Pre-Processor statement");
+       }
+  break;
+#line default
+        }
+        yyTop -= yyLen[yyN];
+        yyState = yyStates[yyTop];
+        int yyM = yyLhs[yyN];
+        if (yyState == 0 && yyM == 0) {
+          if (debug != null) debug.shift(0, yyFinal);
+          yyState = yyFinal;
+          if (yyToken < 0) {
+            yyToken = yyLex.advance() ? yyLex.token() : 0;
+            if (debug != null)
+               debug.lex(yyState, yyToken,yyname(yyToken), yyLex.value());
+          }
+          if (yyToken == 0) {
+            if (debug != null) debug.accept(yyVal);
+            return yyVal;
+          }
+          goto yyLoop;
+        }
+        if (((yyN = yyGindex[yyM]) != 0) && ((yyN += yyState) >= 0)
+            && (yyN < yyTable.Length) && (yyCheck[yyN] == yyState))
+          yyState = yyTable[yyN];
+        else
+          yyState = yyDgoto[yyM];
+        if (debug != null) debug.shift(yyStates[yyTop], yyState);
+        goto yyLoop;
+      }
+    }
+  }
+
+   static  short [] yyLhs  = {              -1,
+    1,    1,    2,    2,    0,    0,    4,    4,    8,    8,
+    9,    9,    9,   13,   13,   13,   14,   14,   10,   11,
+   12,   15,   15,    6,    6,   19,   16,   21,   16,   22,
+   22,   22,   22,   22,   22,   23,   23,   23,   23,   23,
+   23,   24,   24,   25,   25,    5,    5,   26,   26,   27,
+   28,   28,   29,   29,   31,   31,   31,    7,    7,   33,
+   35,   33,   34,   37,   37,   36,   36,   40,   38,   42,
+   43,   38,   41,   41,   41,   39,   39,   44,   44,   45,
+   45,   45,   46,   46,   47,   47,   49,   50,   18,   17,
+   20,   20,   20,   20,   20,   20,   59,   62,   52,   58,
+   58,   60,   60,   51,   51,   64,   64,   65,   65,   65,
+   65,   65,   65,   65,   65,   65,   65,   65,   65,   65,
+   65,   65,   67,   53,   66,   66,   68,   68,   71,   69,
+   70,   70,   70,   70,   70,   70,   70,   75,   61,   61,
+   79,   79,   80,   81,   81,   81,   81,   81,   81,   81,
+   73,   73,   85,   82,   91,   92,   83,   94,   95,   56,
+   96,   96,   93,   93,   97,   97,   98,   99,   99,   99,
+   99,   99,   99,   77,  103,   57,  102,  102,  104,  104,
+  105,  106,  105,  108,  111,  113,  114,   54,  110,  110,
+  115,  115,  116,  112,  117,  117,  118,  118,  119,  120,
+  120,  121,  121,   76,  124,  122,  109,  109,   86,   86,
+  125,  125,  123,  123,  129,  129,  127,  127,  130,  131,
+  126,  133,  128,  132,  132,  132,   74,  136,  136,   55,
+   55,   84,  138,  139,   72,   32,   32,  140,  141,  141,
+  142,  134,  134,  145,  145,  146,  146,  146,  146,   88,
+   88,  147,  147,  149,   87,   89,  148,  148,  148,  148,
+  148,  153,  153,  151,  151,  151,  151,  151,  159,  159,
+  159,  161,  162,  160,  158,  157,  157,  164,  165,  166,
+  166,  167,  167,  135,  135,  170,  168,  169,  169,  171,
+  174,  172,  156,  175,  175,  175,  177,  177,  177,  176,
+  176,  178,  178,  179,  179,  180,  180,  181,  181,  181,
+  181,  182,  182,  155,  183,  183,  183,  185,  185,  187,
+  150,  150,  188,  189,   78,   78,  190,  137,  137,  193,
+  194,  194,  191,  101,  101,   90,  192,  192,  192,  195,
+  144,  144,  196,  196,  197,  197,  198,  198,  143,  143,
+  199,  199,  200,  201,  201,  201,  201,  202,  202,  202,
+  202,  202,  202,  202,  202,  202,  202,  203,  203,  203,
+  203,  203,  203,  212,  212,  212,  211,  210,  210,  204,
+  208,  208,  213,  184,  184,  206,  154,  215,  215,  216,
+  216,  216,  216,  217,  107,  163,  163,  205,  205,  209,
+  209,  209,  219,  219,  219,  219,  219,  219,  219,  219,
+  219,  219,  219,  207,  220,  220,  152,  152,  152,  221,
+  221,  221,  222,  222,  223,  223,  224,  224,  224,  225,
+  225,  226,  226,  226,  227,  227,  227,  227,  227,  227,
+  227,  227,  227,  228,  228,  229,  229,  229,  230,  230,
+  230,  218,  218,  186,  186,  186,  186,  186,  186,  186,
+  186,  186,  186,   48,  173,  100,  100,   63,   63,   30,
+  214,  214,  231,  231,  231,  231,  232,  232,  232,  233,
+  233,  233,  233,  233,  234,  234,    3,    3,    3,    3,
+  235,    3,  236,    3,  237,    3,  238,    3,    3,
+  };
+   static  short [] yyLen = {           2,
+    1,    1,    1,    2,    5,    5,    0,    1,    1,    2,
+    1,    1,    1,    0,    1,    1,    1,    1,    4,    4,
+    4,    0,    1,    1,    2,    0,    3,    0,    3,    1,
+    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+    1,    0,    1,    1,    3,    0,    1,    1,    2,    3,
+    1,    3,    1,    3,    0,    2,    3,    0,    1,    1,
+    0,    3,    4,    0,    1,    1,    3,    0,    3,    0,
+    0,    6,    1,    1,    1,    0,    3,    0,    1,    1,
+    3,    1,    1,    3,    1,    3,    3,    0,    8,    2,
+    1,    1,    1,    1,    1,    1,    0,    0,   11,    0,
+    3,    0,    3,    0,    1,    1,    2,    1,    1,    1,
+    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+    1,    1,    0,    8,    0,    1,    1,    2,    0,    4,
+    1,    1,    1,    1,    1,    1,    1,    3,    0,    1,
+    1,    2,    3,    1,    1,    1,    1,    1,    1,    1,
+    1,    1,    0,   13,    0,    0,   15,    0,    0,   10,
+    0,    1,    0,    1,    1,    2,    2,    1,    1,    1,
+    1,    1,    1,    6,    0,    9,    0,    1,    1,    2,
+    3,    0,    6,    6,    0,    0,    0,   11,    0,    1,
+    1,    2,    3,    1,    0,    1,    1,    2,    3,    1,
+    1,    4,    6,    1,    0,   12,    0,    3,    0,    2,
+    1,    3,    2,    2,    0,    1,    0,    1,    0,    0,
+   11,    0,   11,    0,    2,    5,    3,    0,    1,    7,
+    8,    0,    0,    0,   12,    0,    1,    1,    1,    3,
+    7,    0,    1,    2,    1,    1,    1,    1,    1,    0,
+    2,    1,    3,    3,    0,    0,    1,    1,    5,    5,
+    3,    0,    3,    1,    1,    1,    1,    1,    1,    1,
+    1,    2,    2,    2,    6,    1,    1,    6,    9,    0,
+    1,    1,    2,    0,    1,    0,    5,    0,    1,    3,
+    0,    9,    1,    7,   10,    6,    7,   10,    6,    0,
+    1,    1,    3,    3,    1,    0,    1,    1,    1,    1,
+    1,    0,    1,    1,    1,    1,    1,    5,    2,    1,
+    1,    1,    2,    2,    1,    3,    3,    1,    3,    3,
+    1,    3,    3,    0,    2,    1,    1,    3,    6,    0,
+    0,    2,    1,    1,    2,    3,    1,    3,    0,    1,
+    1,    2,    3,    0,    1,    3,    2,    1,    1,    1,
+    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+    1,    1,    1,    1,    1,    1,    1,    1,    1,    3,
+    3,    3,    1,    4,    5,    3,    1,    1,    3,    1,
+    2,    0,    2,    1,    1,    0,    1,    1,    1,    6,
+    6,    4,    1,    1,    1,    1,    1,    1,    1,    1,
+    1,    1,    1,    4,    1,    3,    1,    2,    2,    1,
+    3,    3,    1,    3,    1,    3,    1,    3,    3,    1,
+    3,    1,    3,    3,    1,    3,    3,    3,    3,    3,
+    3,    3,    4,    1,    2,    1,    3,    3,    1,    3,
+    3,    1,    3,    3,    4,    4,    4,    4,    4,    4,
+    4,    4,    4,    1,    1,    1,    1,    1,    3,    1,
+    1,    1,    1,    1,    1,    1,    1,    1,    1,    0,
+    1,    1,    1,    1,    1,    1,    8,    4,    4,    6,
+    0,    6,    0,    6,    0,    4,    0,    5,    3,
+  };
+   static  short [] yyDefRed = {            0,
+    3,    0,    0,    0,    0,    4,    0,    0,    9,   11,
+   12,   13,    0,    0,    0,    0,    0,  495,  493,    0,
+  491,    0,    0,    0,    0,   48,   10,   17,   18,    0,
+   16,   15,    0,    0,  499,    0,    0,    0,  497,    0,
+    0,    0,    0,   31,   33,   34,   35,   32,   30,    0,
+    0,    0,   51,   53,    0,    0,    0,   24,    0,    0,
+   60,   49,    0,    0,    0,    0,  496,  379,  378,    0,
+    0,  489,    0,    0,  488,    0,    0,    0,    0,   73,
+   74,   44,    0,    0,   66,   70,    5,    0,   25,    6,
+  121,  112,  119,  113,  115,  117,  114,  116,  110,  109,
+  108,  120,  118,  111,  122,   90,    0,  106,    0,    0,
+    0,    0,  301,    0,  498,    0,    0,   54,   45,   52,
+    0,    0,    0,    0,  107,    0,   27,    0,    0,    0,
+    0,    0,    0,   29,   91,   92,   93,   94,   95,   96,
+   62,  490,  494,  492,    0,    0,   69,   67,    2,   65,
+    0,   63,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,  474,  481,    0,  403,  404,  405,  407,  406,
+  475,  408,  409,  410,  411,  412,  413,    0,  479,    0,
+  486,    0,  483,  484,  398,    0,  399,    0,    0,  373,
+  471,  482,  485,  476,    0,    0,    0,    0,  377,  374,
+  375,  376,  371,  372,    0,    0,    0,   79,    0,    0,
+   83,   85,  464,  420,  365,  320,  366,    0,  358,  359,
+  360,  361,  363,  364,  367,  368,  369,  370,    0,  383,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  446,    0,    0,  472,  473,  477,  478,   71,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  487,    0,    0,
+    0,    0,    0,  466,    0,  467,  445,    0,    0,  418,
+  419,    0,   77,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  335,    0,    0,    0,
+    0,  158,    0,    0,    0,    0,  386,    0,    0,  380,
+   87,    0,   84,    0,   86,    0,    0,  390,    0,    0,
+  388,  381,  382,    0,    0,    0,  421,  422,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,  447,  448,    0,    0,   72,    0,    0,    0,
+    0,    0,    0,  237,    0,  239,    0,    0,  175,    0,
+  179,    0,  186,    0,  191,    0,    0,    0,  127,    0,
+    0,    0,    0,    0,    0,  414,    0,  443,  393,  394,
+  391,  384,    0,  402,    0,    0,  468,    0,   98,  246,
+  247,  248,  249,    0,    0,  245,    0,    0,    0,    0,
+    0,  180,    0,    0,  192,  129,    0,  128,    0,    0,
+  159,    0,  165,    0,    0,    0,  318,  389,    0,    0,
+    0,    0,    0,    0,  244,    0,  336,  240,    0,    0,
+    0,    0,    0,    0,  187,  194,    0,  197,    0,    0,
+    0,    0,  229,    0,    0,    0,  173,  170,  171,  168,
+  169,  172,  151,  152,  167,    0,    0,  166,  401,  400,
+    0,  469,    0,    0,    0,    0,  141,   36,   37,   38,
+   39,   40,   41,   43,    0,    0,    0,    0,    0,    0,
+  198,    0,  137,  130,  131,  132,  133,  134,  135,  136,
+  204,    0,    0,    0,  325,    0,    0,    0,    0,    0,
+    0,  331,  328,    0,    0,    0,    0,  142,    0,    0,
+    0,  351,    0,    0,    0,    0,    0,  201,  199,  200,
+    0,    0,  340,    0,    0,    0,  337,    0,    0,    0,
+    0,    0,  153,    0,    0,    0,    0,    0,  150,  147,
+  146,  144,  145,  148,  149,  143,    0,  355,    0,    0,
+  352,    0,    0,    0,    0,    0,    0,  333,  326,    0,
+    0,  327,    0,    0,   56,    0,    0,  232,  329,  332,
+  330,    0,    0,  353,    0,  241,    0,    0,    0,    0,
+    0,    0,    0,    0,  343,  342,  344,    0,  155,   57,
+  255,    0,  356,    0,    0,    0,    0,    0,    0,  345,
+  347,    0,    0,    0,    0,    0,    0,    0,  208,    0,
+    0,  346,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,  256,    0,  252,  257,  258,
+    0,  264,  265,  266,  267,  268,  269,  270,  271,  276,
+  277,  293,  314,    0,    0,  317,  321,  322,    0,    0,
+    0,    0,  339,  348,    0,    0,    0,    0,  272,  465,
+    0,    0,    0,  397,  274,    0,  273,  255,  234,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,  156,    0,    0,    0,  261,    0,  255,    0,    0,
+    0,  253,    0,    0,    0,  454,    0,    0,    0,    0,
+    0,    0,  256,    0,    0,    0,    0,    0,    0,  255,
+    0,    0,    0,  256,    0,    0,    0,  282,    0,  457,
+  458,  463,  455,  456,  462,  461,  459,  460,    0,    0,
+    0,    0,    0,  213,  218,    0,  216,  214,  256,  259,
+    0,  263,  260,    0,  254,    0,    0,  289,    0,    0,
+  283,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,  296,  275,    0,  286,  278,  255,    0,    0,  255,
+  225,    0,    0,    0,    0,  255,    0,  294,  290,  255,
+    0,    0,  220,  285,    0,  255,    0,    0,    0,  287,
+    0,    0,    0,    0,    0,    0,  255,  279,  256,  226,
+  256,  295,    0,    0,    0,    0,    0,  299,    0,    0,
+  255,  297,    0,    0,    0,    0,    0,    0,  298,
+  };
+  protected static  short [] yyDgoto  = {             2,
+  150,  151,    6,    7,   24,   56,  362,    8,    9,   10,
+   11,   12,   33,   30,  359,   58,   59,  127,  109,  134,
+  110,   82,  484,  485,  206,   25,   26,   52,   53,  264,
+  542,  363,   60,   61,  111,   84,  152,   85,  147,  121,
+   86,  124,  302,  207,  208,  209,  210,  211,  212,  303,
+  106,  135,  136,  137,  138,  139,  140,  361,  304,  399,
+  475,  433,  396,  107,  108,  377,  310,  378,  379,  494,
+  449,  458,  459,  460,  461,  499,  462,  504,  476,  477,
+  556,  463,  464,  602,  578,  312,  699,  636,  679,  537,
+  614,  718,  421,  382,  467,    0,  422,  423,  465,  397,
+  437,  369,  411,  370,  371,  441,  328,  528,  592,  373,
+  309,  445,  414,  490,  374,  375,  446,  447,  448,  529,
+  530,  501,  715,  691,  381,  716,  744,  717,  748,  780,
+  802,  766,  796,  404,  795,  466,  511,  601,  701,  364,
+  365,  366,  520,  572,  405,  406,  637,  638,  700,  639,
+  640,  214,  696,  329,  642,  643,  644,  645,  646,  647,
+  648,  649,  675,  650,  651,  726,  727,  728,  757,  790,
+  758,    0,  671,    0,  652,  114,  772,    0,    0,    0,
+    0,    0,  653,  215,  216,  656,  217,  657,  658,  505,
+  506,  538,  513,  514,  568,  596,  597,  612,  521,  522,
+  559,  218,  219,  220,  221,  222,  223,  224,  225,  226,
+  227,  228,  229,  230,  330,  331,  391,  231,  232,  233,
+  234,  235,  236,  237,  238,  239,  240,  241,  242,  243,
+  244,  245,  246,  247,   41,   38,   37,   71,
+  };
+  protected static  short [] yySindex = {         -277,
+    0,    0,  -42, -263, -240,    0, -236, -244,    0,    0,
+    0,    0, -254, -100, -100, -207, -165,    0,    0, -312,
+    0, -383,    9,  -51, -236,    0,    0,    0,    0, -277,
+    0,    0, -277, -277,    0,  -33,   92, -274,    0,  100,
+ -274,  -41,  125,    0,    0,    0,    0,    0,    0,   29,
+   59, -250,    0,    0, -230, -247, 3240,    0,    0,    0,
+    0,    0,   86,   86,   86, -274,    0,    0,    0,   88,
+  188,    0,   88,   93,    0,    9,    9,    9,   86,    0,
+    0,    0,    0,  -78,    0,    0,    0, 2192,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0, 2192,    0,  177,  736,
+  -51,  223,    0,  243,    0,  256,  119,    0,    0,    0,
+  165, -230, -223,  179,    0,    9,    0,    9,  -72,    9,
+    9,    9,    9,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,  187, 3081,    0,    0,    0,    0,
+   86,    0,    9,  -91, -277,    9,    9,  343, -277, -277,
+ -277,  304,    0,    0, 3385,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  206,    0,  231,
+    0,  258,    0,    0,    0,  248,    0, 1614, 3081,    0,
+    0,    0,    0,    0, 3233, 3081, 3233, 3233,    0,    0,
+    0,    0,    0,    0,  238,   59,  265,    0,  270,  277,
+    0,    0,    0,    0,    0,    0,    0, -354,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  288,    0,
+  310,  309,  298, -113,  303,  413,   97,  312,   34,  323,
+    0,  373,  289,    0,    0,    0,    0,    0,   86,   86,
+  347,  348, 1614, -277,   86,   86, -299,    0, -133, 3081,
+ 3081, 1614,  290,    0,  359,    0,    0, -235,  358,    0,
+    0, 3081,    0, 3081,    9, 2473,    9,    9, 3081, 3081,
+ 3385, 3233, 3233, 3233, 3233, 3233, 3233, 3233, 3233, 3233,
+ 3233, 3233, 3233, 3233, 3233, 3233, 3233, 3081, 3081, 3081,
+ 3081,  165,  -51,  449,  -51,  -51,    0, -239,  450,  -51,
+    9,    0, 2473,  372,  381,  375,    0, 2473, 1614,    0,
+    0,  277,    0,  238,    0, 3081, 3081,    0,  386,  385,
+    0,    0,    0,  289,  390, -354,    0,    0, -113,  303,
+  413,  413,   97,  312,  312,   34,   34,   34,   34,   34,
+   34,   34,    0,    0,  373,  373,    0,  -51,  500, 1614,
+  482,  195,  397,    0,  398,    0,  399,    9,    0,  -51,
+    0, 1614,    0,  450,    0, 2192,  517,  -51,    0,   59,
+  417, 2192,  424, 1614, 1614,    0,  438,    0,    0,    0,
+    0,    0, 2473,    0,  509, -217,    0, 1614,    0,    0,
+    0,    0,    0,    9,  195,    0,  343,  -51, -277, -277,
+  554,    0, -217,  -51,    0,    0,  525,    0,    9, 2149,
+    0, 2192,    0,    0,  453,  454,    0,    0, -277, 1614,
+   86, -217,  -51,  731,    0, -277,    0,    0,   86,   86,
+  463,  561,   86, 2192,    0,    0,  -51,    0, 1957, -277,
+   59,    9,    0,    9,    9, -116,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    9,  567,    0,    0,    0,
+   86,    0,   86, 2192,  574,  -51,    0,    0,    0,    0,
+    0,    0,    0,    0,  478,   86, 3081, -277,   99,  584,
+    0,    9,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,   86,  731, -184,    0,  625,  629,  731,  488,  488,
+ -161,    0,    0, -252,  518, 1957,  618,    0, 3081,  343,
+  478,    0, -277,   86,    9,    9,    9,    0,    0,    0,
+  581,  731,    0,    9,   86,  218,    0,  491, 1614,  488,
+   87, -277,    0,    9,   86,    9,  491, -277,    0,    0,
+    0,    0,    0,    0,    0,    0, -277,    0,  114,  491,
+    0,   86,  731,  731,  488, -277,  503,    0,    0, 1614,
+ 2929,    0,  589,  343,    0,  506,   86,    0,    0,    0,
+    0,   86,   86,    0, 3081,    0,  488,  503, -277,   86,
+  -51,  343,  519, 2777,    0,    0,    0, -277,    0,    0,
+    0,  589,    0,  343,  343,   86,  513,  589, 2473,    0,
+    0,  -80,   86,  589, 2321, -277, -277, -277,    0, -277,
+  514,    0, 2929, -277, 3233,    9,    9,  456, 3081,    9,
+ 3233, 3081, 3081, 3081, -223,    0, -223,    0,    0,    0,
+  919,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,   86,   86,
+   86,   86,    0,    0,   86,  522,  523,  526,    0,    0,
+   88,  530,  532,    0,    0, -223,    0,    0,    0, 2321,
+  538,  541, 2625,  547,  551,  553,  560,  563,  577, 2321,
+  -51,    0,  688, -223, 2473,    0,  712,    0, 2321,  704,
+  691,    0, 3081, 3081, 3081,    0, 3081, 3081, 3081, 3081,
+ 3081, 3081,    0, -272,  692,  -51,  -51, 2321, 3081,    0,
+  591, 3081,  699,    0,    9,  126,  704,    0,  620,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  705, -277,
+  613,  661,  656,    0,    0,  713,    0,    0,    0,    0,
+  486,    0,    0,  645,    0,  769, -223,    0,  643, -223,
+    0, -277,  652,   86,  -31, -277, -277,  739, -223, 3081,
+  718,    0,    0, 1614,    0,    0,    0,   86, -277,    0,
+    0,    9,   86,   86,  733,    0,   88,    0,    0,    0,
+  740,   86,    0,    0,  343,    0, -277,  744, -223,    0,
+  658, 2321,  640, 2321,   86,  737,    0,    0,    0,    0,
+    0,    0,  516,  749,  757, -223,  741,    0,  745,  693,
+    0,    0, -277, -277,  767,   86,   86,  753,    0,
+  };
+  protected static  short [] yyRindex = {            0,
+    0,    0, 7141,    0,    0,    0, 7429, 7213,    0,    0,
+    0,    0,    0,  772,  772,    0,    0,    0,    0,    0,
+    0,    0,    0, 3449, 7501,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0, -288,
+ 5251,    0,    0,    0,    0, 8024,  728,    0,  732,  730,
+    0,    0, 6925, 6997, 7069,    0,    0,    0,    0,  774,
+    0,    0,  774,    0,    0,    0,    0,    0, 7285,    0,
+    0,    0,  468,    0,    0,    0,    0,  728,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  -19,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+   44,    0,  840,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,  252,    0,    0,    0,    0,
+  557,    0,    0,    0,    0,    0,    0,  775,    0,    0,
+    0,    0,    0,    0,  664,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0, 5324,  664,    0,
+    0,    0,    0,    0,  664,  664,  664,  664,    0,    0,
+    0,    0,    0,    0, 5776, 5447,    0,    0,  673,  674,
+    0,    0,    0,    0,    0,    0,    0, 5582,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  403,    0, 5729, 5826, 5948, 6043, 6212, 6331, 6468,  360,
+    0,  333,  189,    0,    0,    0,    0,    0, 7573, 3558,
+    0,    0,  122,    0, 7602, 3807, 5253,    0,    0,  664,
+  664,  679,    0,    0, 5544,    0,    0,    0,    0,    0,
+    0,  664,    0,  664,    0,  539,    0,    0,  664,  664,
+  664,  664,  664,  664,  664,  664,  664,  664,  664,  664,
+  664,  664,  664,  664,  664,  664,  664,  664,  664,  664,
+  664,   44, 7912, 3640,   91,   91,    0, -122, 7697, 4834,
+    0,    0,  539,    0,    0,    0,    0,  539, 6503,    0,
+    0,  686,    0,    0,    0,  664,  664,    0,    0,  687,
+    0,    0,    0,  389,    0, 5679,    0,    0, 5876, 5991,
+ 6093, 6162, 6262, 6381, 6431, 6540, 6590, 6627, 6640, 6706,
+ 6749, 6819,    0,    0, 1572, 1686,    0, 7952,    0, -159,
+ 3892,   60,    0,    0,  689,    0,    0,    0,    0, -117,
+    0, -159,    0, 7732,    0,  395,    0, 4919,    0, 3974,
+ 5001,  422,    0,  679,  679,    0,    0,    0,    0,    0,
+    0,    0,  539,    0,    0,    0,    0, -159,    0,    0,
+    0,    0,    0,    0, -246,    0,  775,  103,    0,  682,
+    0,    0,    0, 1808,    0,    0,    0,    0,    0,   71,
+    0,  670,    0, 5374,    0,    0,    0,    0,    0, -159,
+ 3725,    0, 5086, -233,    0,    0,    0,    0,  925, -206,
+    0,    0, 7667,  152,    0,    0, 2000,    0,   71,    0,
+ 4084,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+ 7357,    0, 4166,  395,    0, 5168,    0,    0,    0,    0,
+    0,    0,    0,    0, -181, 1009,  664,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0, 1093,  -88,    0,    0,  -38,    0, -186,  794,  -65,
+    0,    0,    0, -114,    0,   71,    0,    0,  550,  286,
+ -112,    0,    0, 1177,    0,    0,    0,    0,    0,    0,
+    0, -186,    0,    0, 4251,  -23,    0, -189,   30,  319,
+  103,    0,    0,    0, 4333,    0, -189,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,  207,
+    0, -195, -218, -218,  794,    0,  461,    0,    0,   10,
+  664,    0,  795,   90,    0,    0, 1553,    0,    0,    0,
+    0, 1261, 1345,    0,  571,    0, -237,   48,    0, 1429,
+   91,   90,   80,  664,    0,    0,    0,    0,    0,    0,
+    0,  795,    0,  775,  775, 7762,    0,  795,  539,    0,
+    0,    0, 4418,  795, -282,    0,    0,    0,    0,    0,
+    0,    0,  664,    0,  664,    0,    0,    0,  664,    0,
+  664, -151,  664, -151,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,  216,  835,    0,    0,    0, 1745, 7797,
+ 7827,   25,    0,    0, 1745,    0,  -90,  -45,    0,    0,
+  -14,  -13,    0,    0,    0,    0,    0,    0,    0,  268,
+    0,    0,  664,    0,    0,    0,    0,    0,    0, -282,
+ -262,    0,    0,    0,  539,    0,    0,    0,  371,  240,
+    0,    0,  664,  664,  664,    0,  664,  664,  664,  664,
+  664,  664,    0,    0,    0, -251,  156, -282,  664,    0,
+    0,  664,    0,    0,    8,    0,  245,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  799,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0, 1937, -215,    0,    0,    0,    0,  664,
+    0,    0,    0,   12,    0,    0,    0, 4500,    0,    0,
+    0, -249, 2129, 4585,    0,    0,  -14,    0,    0,    0,
+    0, 4667,    0,    0,  697,    0,    0,    0,    0,    0,
+    0, -282,    0, -282, 4752,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0, -287, -278,    0,    0,
+  };
+  protected static  short [] yyGindex = {            0,
+ -394,    1,    0,    0,    0,  809,  -20,    0, 1107,    0,
+    0,    0, 1105,    0,    0,  -50,    0,    0,    0, -136,
+    0,  -16,    0,  192,   23,    0, 1096,    0, 1045,  462,
+  139, -304,    0, 1013,    0,    0,    0, 1004,  825,    0,
+    0,    0,    0,    0,    0,    0,  856,  355,  857,    0,
+  580,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0, -327,    0, 1024,    0,    0,    0,  758,    0,
+    0, -419, -411, -210, -200,  619, -198,  515,    0,  666,
+    0,    0,    0,    0,    0,  181, -590, -216, -137, -389,
+    0,    0,    0,    0,    0,    0,    0,  721,    0, -183,
+  982,    0,    0,    0,  776,    0,  -52,    0,  559,    0,
+    0,    0,    0,    0,    0,  771,    0,    0,  702,    0,
+    0,    0,    0,    0,    0,  435,    0,  439,    0,    0,
+    0,    0,    0,  391,    0,    0,  527,    0,    0,    0,
+    0,  759,    0, -211,    0,  761,    0,  489, -229,    0,
+    0, -154,    0, -305,    0,    0,    0,    0,    0,    0,
+    0,    0,  534,    0,    0,    0,    0,  444,    0,    0,
+    0,    0,  402,    0,    0,  -73,  361,    0,    0,    0,
+    0,    0,    0, -511, -196,    0,    0,    0,    0,  639,
+ -457,  662,  631,    0,    0, -542,    0,    0,    0,  657,
+    0, -143,    0,    0,    0,    0,    0,    0,    0,  416,
+    0,    0,    0, -185,    0,  784,    0,    0,    0,    0,
+  897,  898,  401,  899,  442,  698,    0,  -94,  436,  906,
+    0,    0,    0,    0,    0,    0,    0,    0,
+  };
+  protected static  short [] yyTable = {           116,
+    3,  367,  266,   57,  265,   89,   50,  383,  512,   87,
+  615,   39,  387,  536,   28,   16,  284,  436,  221,  243,
+   44,  259,  243,  250,   13,  311,   42,  223,   55,  495,
+   63,    1,   42,   64,   65,   88,   80,  496,   44,   68,
+  223,  243,  270,  271,  413,   51,  740,   42,   17,   14,
+  242,  611,   79,  242,  217,  276,   58,   45,    1,  277,
+  119,   50,  181,   18,   19,   20,  243,  266,  690,  307,
+  432,   55,  242,  183,  692,   43,  266,   51,  316,   42,
+  664,  181,   46,   21,  349,    1,  512,  221,  580,   23,
+   42,    1,  183,  213,  267,  319,  550,  242,   51,  181,
+   51,   35,  741,  654,  551,  243,  181,    5,   81,    4,
+  183,  155,   58,  158,  159,  160,  161,  183,   69,  341,
+   15,   47,   42,   58,    1,   44,   44,  337,  338,  205,
+  560,  480,  221,  266,   29,  388,  242,  336,   42,  251,
+  252,  223,  243,  269,   51,  181,   58,    1,  154,  480,
+   40,   58,   44,  350,  249,  250,  183,  396,   48,  255,
+  256,  257,  546,  284,   78,   58,  243,    5,  654,  512,
+   58,   45,   55,  242,  266,   51,   42,   42,  654,   42,
+   55,   42,  181,  177,  599,   42,  266,  654,  178,  793,
+   58,   42,  149,  183,  334,   58,   46,  430,  266,  266,
+  425,  426,  608,  353,  354,  804,  654,  314,  315,  289,
+   51,  290,  266,  181,  617,  618,  243,    1,  324,  213,
+   42,  213,   22,   42,  183,  341,  341,  335,  509,   58,
+  534,  349,   49,  349,   58,   47,  576,  349,  497,  400,
+  678,  401,  680,   55,  266,  156,  472,  242,  498,  105,
+  500,   31,   32,  544,  308,  480,  181,  205,  324,   55,
+  332,  333,  480,  323,  396,  105,   58,  183,  105,  105,
+  334,   58,   48,  389,  390,   51,  313,   44,  105,  105,
+  277,  698,   88,  457,   51,  480,  607,  368,  105,  376,
+  654,  105,  654,  105,  300,  262,   45,   36,  105,  720,
+  350,  334,  350,  621,  334,  552,  350,   89,  282,  283,
+  105,    4,  493,  207,  157,  553,  288,  555,  480,  105,
+  480,   46,   77,  402,  105,  324,   42,   42,  242,  403,
+   42,  622,  105,  380,  623,  581,  122,   88,  480,  228,
+   58,   51,  123,  205,  105,   58,   49,  242,  586,  368,
+  266,  410,  307,  266,  480,  573,  207,  376,  228,   58,
+   47,   58,  775,   58,    5,  777,  105,  105,   55,  105,
+  323,   58,  242,   58,  786,   58,  334,  334,   58,  549,
+  334,  781,   51,  228,  266,   66,  593,  434,  338,  721,
+   58,  480,  480,  444,   51,  480,  431,   48,  334,  205,
+   67,  300,  262,   58,  807,  803,   51,   51,   72,  439,
+  440,  242,  474,  443,  334,   58,  525,   74,  655,  480,
+   51,  821,  228,  288,  480,  480,  444,  480,  480,  471,
+  480,  759,  473,   75,  523,  503,  486,  507,  508,  510,
+  760,  451,   58,  105,  205,   58,  480,   76,  242,  503,
+  502,   58,   51,   70,   58,  474,   73,   58,   76,  228,
+  641,  215,  526,   58,   76,  400,  558,  401,  723,  104,
+  666,   49,   77,  713,   58,  532,  673,  113,  289,   58,
+  290,  112,  724,  655,   54,  527,   44,  163,  524,  164,
+  751,   58,    5,  655,  338,  338,  115,  452,  338,  575,
+  171,  749,  655,  236,  535,   45,   55,  117,  563,  564,
+  565,  545,  179,  286,  287,  104,   83,  503,  595,  181,
+  126,  655,  242,  562,  315,  641,  584,  503,  585,  503,
+   46,  142,  603,  228,  480,  641,  480,  118,  104,   54,
+  480,  595,  577,  251,  641,  280,  183,  791,  582,  402,
+  281,  143,  184,   58,  280,  403,  798,  583,   51,  281,
+  800,   51,  570,  641,  144,   58,  590,  145,  191,   47,
+  595,  251,  251,  251,  146,  739,  670,  813,  452,  674,
+  676,  674,  251,   83,   55,  809,  755,  811,  266,  606,
+  789,  825,   51,  452,  153,  192,  193,  694,  613,  162,
+  452,  452,  194,  452,  452,  655,   48,  655,  253,  503,
+  503,  768,  258,  672,  248,  260,  659,  660,  661,  341,
+  662,  341,  444,  444,  665,  365,  321,   55,  323,  365,
+  706,  315,  365,  365,  365,  298,  299,  365,  365,  365,
+  261,  449,  365,   55,  300,  301,  250,  641,  543,  641,
+  730,  731,  732,  291,  733,  734,  735,  736,  737,  738,
+  365,  263,  365,  104,   78,  480,  750,  262,  444,  753,
+  714,  814,  272,  815,  250,  250,  250,  273,  574,  104,
+   49,  480,  104,  104,  274,  250,  341,  342,  449,  449,
+  104,  275,  104,  104,  533,  743,  746,  453,  334,  540,
+  334,  278,  104,  589,  334,  104,  104,  104,  756,  104,
+  104,  395,  104,  799,  279,  444,  444,  670,  280,  104,
+  104,  281,  449,  567,  104,  604,  207,  163,  284,  104,
+  344,  345,  104,  104,  104,  355,  356,  449,  288,  104,
+  764,  292,  293,  294,  449,  449,  104,  449,  449,  444,
+  285,  104,  317,  598,  587,  588,  305,  306,  104,  295,
+  104,  296,  778,  297,  444,  794,  783,  784,  318,  207,
+  320,  444,  444,  104,  444,  444,  360,  372,  453,  792,
+  104,  104,  616,  104,  480,  207,  384,  386,  620,  769,
+  770,  771,  395,  453,  624,  385,   51,  805,  392,  393,
+  453,  453,  394,  453,  453,  395,  398,  104,  104,  407,
+  104,  409,  408,    1,  395,  395,    1,  395,  395,  816,
+  770,  817,  417,  826,  827,    1,    1,    1,    1,    1,
+    1,  419,    1,    1,    1,    1,  424,    1,    1,    1,
+    1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
+  427,    1,  429,    1,    1,    1,    1,  104,    1,  442,
+    1,    1,    1,  450,    1,  469,  470,    1,  488,    1,
+    1,    1,  515,    1,    1,    1,    1,   68,    1,  517,
+    1,  487,   68,   75,  104,    1,    1,  519,   68,  531,
+  536,    1,  268,    1,  539,    1,    1,  541,    1,    1,
+    1,    1,  557,  548,    1,    1,    1,    1,    1,  571,
+  566,    1,  591,  311,    1,    1,    1,    1,  600,    1,
+    1,    1,    1,    1,    1,  619,  663,    1,  609,    1,
+  669,    1,    1,    1,    1,    1,  693,  534,  104,  695,
+  544,    1,    1,    1,    1,    1,  697,    1,  719,    1,
+    1,  392,  480,  392,  104,  416,  703,  104,  104,  704,
+    1,  420,  354,  480,  354,  707,    1,  104,  104,  708,
+    1,  709,  722,    1,    1,  164,    1,  104,  710,  725,
+  104,  711,  104,  357,  480,  357,   59,  104,  346,  347,
+  348,  349,  350,  351,  352,  712,  729,  742,   59,  104,
+   59,  420,   59,  752,  754,    1,  762,    1,  104,    1,
+  763,    1,  104,    1,   59,    1,   28,   59,   59,    1,
+  128,  104,  765,  489,  767,  104,   59,   59,   59,   28,
+  741,  740,  773,  129,  774,  104,  776,   59,  779,   28,
+   59,  788,   59,  130,  785,  801,   59,   59,   59,  806,
+  797,  808,  810,  516,  819,  104,  104,  104,  104,   59,
+  812,   28,  820,  823,  822,  131,  104,  824,   59,   59,
+   28,  104,  828,   59,  132,   26,  829,  480,   59,   59,
+   14,   59,  300,  334,   59,   80,   82,   59,   59,   59,
+   59,  480,   59,   59,   59,   59,   64,   59,   81,  387,
+  182,  238,   55,  209,   59,   59,   59,  224,   64,  334,
+   64,  358,   64,  104,   27,   59,   59,   28,   59,   34,
+   62,  133,  120,  141,   64,  148,  357,   64,   64,  322,
+  125,  325,  104,   59,  554,  418,   64,   64,   64,  254,
+  667,  518,  468,  316,  415,  412,  605,   64,  491,   61,
+   64,  747,   64,  668,  745,  782,   64,   64,   64,  478,
+  479,  480,  481,  482,  483,  435,  438,  677,  702,   64,
+  761,  787,  569,  818,  579,  547,  428,  561,   64,   64,
+  339,  230,  340,   64,  334,    0,  343,    0,   64,   64,
+    0,   64,   59,  230,   64,    0,    0,   64,   64,   64,
+   64,    0,   64,   64,   64,   64,    0,   64,    0,  230,
+    0,    0,  230,  230,   64,   64,   64,    0,    0,    0,
+    0,  230,  230,  230,    0,   64,   64,    0,   64,    0,
+  230,    0,  230,    0,    0,  230,    0,  230,    0,    0,
+    0,  230,  230,   64,  320,    0,    0,    0,  320,    0,
+  316,  320,  320,  320,  230,    0,  320,  320,  320,   64,
+    0,  320,    0,  230,  230,  231,    0,    0,  230,    0,
+    0,    0,    0,  230,  230,    0,  230,  231,    0,  320,
+    0,  320,  230,  230,  230,    0,    0,  230,  230,  230,
+  230,    0,  230,  231,    0,    0,  231,  231,    0,    0,
+  230,  230,   64,    0,    0,  231,  231,  231,    0,    0,
+  230,  230,    0,  230,  231,    0,  231,    0,    0,  231,
+    0,  231,    0,    0,    0,  231,  231,    0,  230,    0,
+    0,    0,    0,    0,    0,  681,  682,  683,  231,    0,
+  684,  685,  686,    0,  230,  687,    0,  231,  231,  124,
+    0,    0,  231,    0,    0,    0,    0,  231,  231,    0,
+  231,  124,    0,  688,    0,  689,  231,  231,  231,    0,
+    0,  231,  231,  231,  231,    0,  231,  124,    0,    0,
+  124,  124,    0,    0,  231,  231,    0,  230,    0,  124,
+  124,  124,    0,    0,  231,  231,    0,  231,  124,    0,
+  124,    0,    0,  124,    0,  124,    0,    0,    0,  124,
+  124,    0,  231,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,  124,    0,    0,    0,    0,    0,  231,    0,
+    0,  124,  124,  176,    0,    0,  124,    0,    0,    0,
+    0,  124,  124,    0,  124,  176,    0,    0,    0,    0,
+  124,  124,  124,    0,    0,  124,  124,  124,  124,    0,
+  124,  176,    0,    0,  176,  176,    0,    0,  124,  124,
+    0,  231,    0,  176,  176,  176,    0,    0,  124,  124,
+    0,  124,  176,    0,  176,    0,    0,  176,    0,  176,
+    0,    0,    0,  176,  176,    0,  124,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  176,    0,    0,    0,
+    0,    0,  124,    0,    0,  176,  176,  160,    0,    0,
+  176,    0,    0,    0,    0,  176,  176,    0,  176,  160,
+    0,    0,    0,    0,  176,  176,  176,    0,    0,  176,
+  176,  176,  176,    0,  176,  160,    0,    0,  160,  160,
+    0,    0,  176,  176,    0,  124,    0,  160,  160,  160,
+    0,    0,  176,  176,    0,  176,  160,    0,  160,    0,
+    0,  160,    0,  160,    0,    0,    0,  160,  160,    0,
+  176,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  160,    0,    0,    0,    0,    0,  176,    0,    0,  160,
+  160,   99,    0,    0,  160,    0,    0,    0,    0,  160,
+  160,    0,  160,   99,    0,    0,    0,    0,  160,  160,
+  160,    0,    0,  160,  160,  160,  160,    0,  160,   99,
+    0,    0,   99,   99,    0,    0,  160,  160,    0,  176,
+    0,   99,   99,   99,    0,    0,  160,  160,    0,  160,
+   99,    0,   99,    0,    0,   99,    0,   99,    0,    0,
+    0,   99,   99,    0,  160,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,   99,    0,    0,    0,    0,    0,
+  160,    0,    0,   99,   99,  188,    0,    0,   99,    0,
+    0,    0,    0,   99,   99,    0,   99,  188,    0,    0,
+    0,    0,   99,   99,   99,    0,    0,   99,   99,   99,
+   99,    0,   99,  188,    0,    0,  188,  188,    0,    0,
+   99,   99,    0,  160,    0,  188,  188,  188,    0,    0,
+   99,   99,    0,   99,  188,    0,  188,    0,    0,  188,
+    0,  188,    0,    0,    0,  188,  188,    0,   99,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  188,    0,
+    0,    0,    0,    0,   99,    0,    0,  188,  188,    0,
+    0,    0,  188,    0,    0,    0,    0,  188,  188,    0,
+  188,    0,    0,    0,    0,    0,  188,  188,  188,    0,
+    0,  188,  188,  188,  188,    0,  188,    0,    0,    0,
+    0,    0,    0,    0,  188,  188,    0,   99,    0,    0,
+    0,    0,  233,    0,  188,  188,    0,  188,    0,    0,
+    0,  233,  233,    0,  233,    0,  233,    0,    0,  233,
+  233,  233,  188,  233,  233,  233,  233,    0,  233,  233,
+  233,  233,  233,  233,  233,  233,    0,  233,  188,    0,
+    0,  233,  233,    0,  233,    0,    0,    0,  233,    0,
+    0,    0,    0,    0,    0,  233,  233,    0,    0,    0,
+    0,    0,  233,    0,  233,    0,  233,    0,    0,    0,
+  450,  233,   44,  163,    0,  164,    0,  233,    0,  233,
+    0,  188,    0,    0,  233,  233,  171,  233,    0,    0,
+  233,   45,    0,  233,  233,    0,    0,    0,  179,    0,
+    0,    0,    0,    0,    0,  181,    0,    0,    0,  233,
+    0,    0,    0,  233,    0,  233,   46,  450,  450,    0,
+  233,  233,    0,    0,    0,    0,    0,  233,    0,    0,
+  233,  233,  183,  233,    0,  233,  233,    0,  184,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,  450,  233,    0,  191,   47,  233,    0,    0,  233,
+  233,    0,    0,    0,    0,    0,  450,    0,    0,    0,
+    0,    0,    0,  450,  450,    0,  450,  450,    0,    0,
+    0,  192,  193,    0,  451,    0,    0,    0,  194,    0,
+    0,  233,   48,  233,  255,  233,    0,  233,    0,  233,
+    0,  233,    0,  255,  255,  233,  255,    0,  255,    0,
+    0,  255,  255,  255,    0,  255,  255,  255,  255,    0,
+  255,  255,  255,  255,  255,  255,  255,  255,    0,  255,
+    0,  451,  451,  255,  255,    0,  255,    0,    0,    0,
+  255,    0,    0,    0,    0,    0,    0,  255,  255,    0,
+    0,    0,    0,    0,  255,    0,  255,    0,  255,    0,
+    0,    0,    0,  255,    0,  451,   49,    0,    0,  255,
+    0,  255,    0,    0,    0,    0,  255,  255,    0,  255,
+  451,    0,  255,    0,    0,  255,  255,  451,  451,    0,
+  451,  451,    0,    0,   58,    0,    0,    0,    0,    0,
+    0,  255,    0,  195,    0,  255,    0,  255,    0,    0,
+    0,    0,  255,  255,   58,   58,    0,    0,    0,  255,
+    0,    0,  255,  255,    0,  255,    0,  255,  255,    0,
+    0,    0,    0,    0,    0,    0,    0,   58,    0,    0,
+    0,    0,    0,    0,  255,    0,   58,   58,  255,    0,
+    0,  255,  255,    0,    0,   58,   58,   58,    0,    0,
+   58,   58,   58,   58,    0,   58,    0,    0,    0,    0,
+    0,    0,    0,   58,   58,    0,    0,    0,    0,    0,
+    0,    0,    0,  255,   58,  255,  219,  255,    0,  255,
+    0,  255,    0,  255,    0,  219,  219,  255,  219,    0,
+  219,   58,    0,  219,  219,  219,    0,  219,  219,  219,
+  219,    0,  219,  219,  219,  219,  219,  219,  219,  219,
+    0,  219,    0,    0,    0,  219,  219,    0,  219,    0,
+    0,  128,  219,    0,    0,  452,    0,    0,    0,  219,
+  219,    0,    0,    0,  129,  453,  219,    0,  219,    0,
+  219,    0,    0,    0,  130,  219,    0,  454,    0,    0,
+    0,  219,    0,  219,  455,    0,    0,    0,  219,  219,
+    0,  219,    0,    0,  219,    0,  131,  219,  219,    0,
+    0,    0,    0,    0,    0,  132,   58,    0,    0,    0,
+    0,    0,    0,  219,    0,  196,    0,  219,    0,  219,
+    0,    0,    0,    0,  219,  219,   58,   58,    0,    0,
+  492,  219,    0,    0,  219,  219,    0,  219,    0,  219,
+  219,    0,    0,    0,    0,    0,    0,    0,    0,   58,
+    0,    0,  133,  456,    0,    0,  219,    0,   58,   58,
+  219,    0,    0,  219,  219,    0,    0,   58,   58,   58,
+    0,    0,   58,   58,   58,   58,    0,   58,    0,    0,
+    0,    0,    0,    0,    0,   58,   58,    0,    0,    0,
+    0,    0,    0,    0,    0,  219,   58,  219,  222,  219,
+    0,  219,    0,  219,    0,  219,    0,  222,  222,  219,
+  222,    0,  222,   58,    0,  222,  222,  222,    0,  222,
+  222,  222,  222,    0,  222,  222,  222,  222,  222,  222,
+  222,  222,    0,  222,    0,    0,    0,  222,  222,    0,
+  222,    0,    0,  128,  222,    0,    0,  452,    0,    0,
+    0,  222,  222,    0,    0,    0,  129,  453,  222,    0,
+  222,    0,  222,    0,    0,    0,  130,  222,    0,  454,
+    0,    0,    0,  222,    0,  222,  455,    0,    0,    0,
+  222,  222,    0,  222,    0,    0,  222,    0,  131,  222,
+  222,    0,    0,    0,    0,    0,    0,  132,   91,    0,
+    0,    0,    0,    0,    0,  222,    0,    0,    0,  222,
+    0,  222,    0,    0,    0,    0,  222,  222,   92,    0,
+    0,    0,    0,  222,    0,    0,  222,  222,    0,  222,
+    0,  222,  222,    0,    0,    0,    0,    0,    0,    0,
+    0,   93,    0,    0,  133,  456,    0,    0,  222,    0,
+   94,   95,  222,    0,    0,  222,  222,    0,    0,   96,
+   97,   98,    0,    0,   99,    0,  100,  101,    0,  102,
+    0,    0,    0,    0,    0,    0,    0,  103,  104,    0,
+    0,    0,    0,    0,    0,    0,    0,  222,    0,  222,
+  625,  222,    0,  222,    0,  222,    0,  222,    0,   44,
+  163,  222,  164,    0,  165,  105,    0,  166,  167,  168,
+    0,  169,  170,  171,  172,    0,  173,  174,   45,  626,
+  175,  176,  177,  178,    0,  179,    0,    0,    0,  627,
+  180,    0,  181,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,   46,   68,    0,    0,    0,    0,    0,
+  182,    0,  628,    0,  629,    0,    0,    0,    0,  183,
+    0,    0,    0,    0,    0,  184,    0,  185,    0,    0,
+    0,    0,  186,  187,    0,  188,    0,    0,  190,    0,
+    0,  191,   47,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  630,    0,    0,
+    0,  631,    0,  632,    0,    0,    0,    0,  192,  193,
+    0,    0,    0,    0,    0,  194,    0,    0,  633,   48,
+    0,  634,    0,   69,  635,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  196,    0,    0,  326,    0,    0,    0,  197,  198,    0,
+    0,   44,  163,  327,  164,    0,  165,    0,    0,  166,
+  167,  168,    0,  169,  170,  171,  172,    0,  173,  174,
+   45,    0,  175,  176,  177,  178,    0,  179,    0,  199,
+    0,  200,  180,  201,  181,  202,    0,  203,    0,  204,
+    0,    0,    0,   49,    0,   46,   68,    0,    0,    0,
+    0,    0,  182,    0,    0,    0,    0,    0,    0,    0,
+    0,  183,    0,    0,    0,    0,    0,  184,    0,  185,
+    0,    0,    0,    0,  186,  187,    0,  188,    0,  189,
+  190,    0,    0,  191,   47,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  192,  193,    0,    0,    0,    0,    0,  194,    0,    0,
+    0,   48,    0,    0,    0,   69,    0,  195,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,  196,    0,    0,  705,    0,    0,    0,  197,
+  198,    0,    0,   44,  163,    0,  164,    0,  165,    0,
+    0,  166,  167,  168,    0,  169,  170,  171,  172,    0,
+  173,  174,   45,    0,  175,  176,  177,  178,    0,  179,
+    0,  199,    0,  200,  180,  201,  181,  202,    0,  203,
+    0,  204,    0,    0,    0,   49,    0,   46,   68,    0,
+    0,    0,    0,    0,  182,    0,    0,    0,    0,    0,
+    0,    0,    0,  183,    0,    0,    0,    0,    0,  184,
+    0,  185,    0,    0,    0,    0,  186,  187,    0,  188,
+    0,  189,  190,    0,    0,  191,   47,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,  192,  193,    0,    0,    0,    0,    0,  194,
+    0,    0,    0,   48,    0,    0,    0,   69,    0,  195,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,  196,    0,    0,    0,    0,    0,
+    0,  197,  198,    0,    0,   44,  163,    0,  164,    0,
+  165,    0,    0,  166,  167,  168,    0,  169,  170,  171,
+  172,    0,  173,  174,   45,    0,  175,  176,  177,  178,
+    0,  179,    0,  199,    0,  200,  180,  201,  181,  202,
+    0,  203,    0,  204,    0,    0,    0,   49,    0,   46,
+   68,    0,    0,    0,    0,    0,  182,    0,    0,    0,
+    0,    0,    0,    0,    0,  183,    0,    0,    0,    0,
+    0,  184,    0,  185,    0,    0,    0,    0,  186,  187,
+    0,  188,    0,  189,  190,    0,    0,  191,   47,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,  192,  193,    0,    0,    0,    0,
+    0,  194,    0,    0,    0,   48,    0,    0,    0,   69,
+    0,  195,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  196,  594,  610,    0,
+    0,    0,    0,  197,  198,    0,    0,   44,  163,    0,
+  164,    0,  165,    0,    0,  166,  167,  168,    0,  169,
+  170,  171,  172,    0,  173,  174,   45,    0,  175,  176,
+  177,  178,    0,  179,    0,  199,    0,  200,  180,  201,
+  181,  202,    0,  203,    0,  204,    0,    0,    0,   49,
+    0,   46,   68,    0,    0,    0,    0,    0,  182,    0,
+    0,    0,    0,    0,    0,    0,    0,  183,    0,    0,
+    0,    0,    0,  184,    0,  185,    0,    0,    0,    0,
+  186,  187,    0,  188,    0,  189,  190,    0,    0,  191,
+   47,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  192,  193,    0,    0,
+    0,    0,    0,  194,    0,    0,    0,   48,    0,    0,
+    0,   69,    0,  195,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  196,  594,
+    0,    0,    0,    0,    0,  197,  198,    0,    0,   44,
+  163,    0,  164,    0,  165,    0,    0,  166,  167,  168,
+    0,  169,  170,  171,  172,    0,  173,  174,   45,    0,
+  175,  176,  177,  178,    0,  179,    0,  199,    0,  200,
+  180,  201,  181,  202,    0,  203,    0,  204,    0,    0,
+    0,   49,    0,   46,   68,    0,    0,    0,    0,    0,
+  182,    0,    0,    0,    0,    0,    0,    0,    0,  183,
+    0,    0,    0,    0,    0,  184,    0,  185,    0,    0,
+    0,    0,  186,  187,    0,  188,    0,  189,  190,    0,
+    0,  191,   47,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  192,  193,
+    0,    0,    0,    0,    0,  194,    0,    0,    0,   48,
+    0,    0,    0,   69,    0,  195,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  196,    0,    0,    0,    0,    0,   90,  197,  198,    0,
+    0,   44,  163,    0,  164,    0,  165,    0,    0,  166,
+  167,  168,    0,  169,  170,  171,  172,    0,  173,  174,
+   45,    0,  175,  176,  177,  178,    0,  179,    0,  199,
+    0,  200,  180,  201,  181,  202,   91,  203,    0,  204,
+    0,    0,    0,   49,    0,   46,   68,    0,    0,    0,
+    0,    0,  182,    0,    0,    0,   92,    0,    0,    0,
+    0,  183,    0,    0,    0,    0,    0,  184,    0,  185,
+    0,    0,    0,    0,  186,  187,    0,  188,    0,   93,
+  190,    0,    0,  191,   47,    0,    0,    0,   94,   95,
+    0,    0,    0,    0,    0,    0,    0,   96,   97,   98,
+    0,    0,   99,    0,  100,  101,    0,  102,    0,    0,
+  192,  193,    0,    0,    0,  103,  104,  194,    0,    0,
+    0,   48,    0,    0,    0,   69,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,  196,  105,    0,    0,    0,    0,    0,  197,
+  198,    0,    0,   44,  163,    0,  164,    0,  165,    0,
+    0,  166,  167,  168,    0,  169,  170,  171,  172,    0,
+  173,  174,   45,    0,  175,  176,  177,  178,    0,  179,
+    0,  199,    0,  200,  180,  201,  181,  202,    0,  203,
+    0,  204,    0,    0,    0,   49,    0,   46,   68,    0,
+    0,    0,    0,    0,  182,   58,    0,    0,    0,    0,
+    0,    0,    0,  183,    0,    0,    0,    0,    0,  184,
+    0,  185,    0,    0,    0,    0,  186,  187,    0,  188,
+    0,    0,  190,   58,    0,  191,   47,    0,    0,    0,
+    0,    0,    0,    0,    0,   58,   58,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,   58,    0,    0,    0,
+    0,    0,  192,  193,    0,   58,    0,    0,    0,  194,
+    0,    0,    0,   48,    0,    0,    0,   69,   58,    0,
+    0,    0,    0,    0,    0,    0,    0,   58,   58,    0,
+    0,    0,   58,    0,  196,    0,    0,   58,   58,    0,
+    0,    0,    0,    0,    0,    0,   58,   58,   58,    0,
+    0,   58,    0,   58,   58,    0,   58,    0,    0,    0,
+    0,    0,    0,    0,   58,   58,   97,    0,    0,    0,
+    0,    0,    0,  199,   58,  200,    0,  201,    0,  202,
+    0,  203,   97,  204,    0,   97,   97,   49,    0,    0,
+    0,    0,   58,    0,   97,   97,   97,    0,    0,    0,
+    0,    0,    0,   97,    0,   97,    0,    0,   97,    0,
+   97,    0,    0,    0,   97,   97,    0,    0,    0,    0,
+    0,    0,   97,    0,    0,   97,    0,   97,    0,    0,
+    0,    0,    0,    0,    0,    0,   97,   97,    0,    0,
+    0,    0,    0,    0,    0,    0,   97,   97,  100,   97,
+    0,    0,    0,    0,    0,   97,   97,   97,    0,    0,
+   97,   97,   97,   97,  100,   97,    0,  100,  100,    0,
+    0,    0,    0,   97,   97,    0,  100,  100,  100,    0,
+    0,    0,    0,   97,   97,  100,   97,  100,    0,    0,
+  100,    0,  100,    0,    0,    0,  100,  100,    0,    0,
+    0,   97,    0,    0,  100,    0,    0,    0,    0,  100,
+    0,    0,    0,    0,    0,    0,    0,   97,  100,  100,
+    0,    0,    0,    0,    0,    0,    0,    0,  100,  100,
+    0,  100,    0,  101,    0,    0,    0,  100,  100,  100,
+    0,    0,  100,  100,  100,  100,    0,  100,    0,  101,
+    0,    0,  101,  101,    0,  100,  100,    0,    0,    0,
+   97,  101,  101,  101,    0,  100,  100,    0,  100,    0,
+  101,    0,  101,    0,    0,  101,    0,  101,    0,    0,
+    0,  101,  101,  100,    0,    0,    0,    0,    0,  101,
+    0,    0,    0,    0,  101,    0,    0,    0,    0,  100,
+    0,    0,    0,  101,  101,    0,    0,    0,    0,    0,
+    0,    0,    0,  101,  101,  123,  101,    0,    0,    0,
+    0,    0,  101,  101,  101,    0,    0,  101,  101,  101,
+  101,  123,  101,    0,  123,  123,    0,    0,    0,    0,
+  101,  101,  100,  123,  123,  123,    0,    0,    0,    0,
+  101,  101,  123,  101,  123,    0,    0,  123,    0,  123,
+    0,    0,    0,  123,  123,    0,    0,    0,  101,    0,
+    0,    0,    0,    0,    0,    0,  123,    0,    0,    0,
+    0,    0,    0,    0,  101,  123,  123,    0,    0,    0,
+    0,    0,    0,    0,    0,  123,  123,    0,  123,    0,
+  102,    0,    0,    0,  123,  123,  123,    0,    0,  123,
+  123,  123,  123,    0,  123,    0,  102,    0,    0,  102,
+  102,    0,  123,  123,    0,    0,    0,  101,  102,  102,
+  102,    0,  123,  123,    0,  123,    0,  102,    0,  102,
+    0,    0,  102,    0,  102,    0,    0,    0,  102,  102,
+  123,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,  102,    0,    0,    0,    0,  123,    0,    0,    0,
+  102,  102,    0,    0,    0,    0,    0,    0,    0,    0,
+  102,  102,  211,  102,    0,    0,    0,    0,    0,  102,
+  102,  102,    0,    0,  102,  102,  102,  102,  211,  102,
+    0,  211,  211,    0,    0,    0,    0,  102,  102,  123,
+  211,  211,  211,    0,    0,    0,    0,  102,  102,  211,
+  102,  211,  211,    0,  211,    0,  211,    0,    0,    0,
+  211,  211,    0,    0,    0,  102,    0,    0,    0,    0,
+    0,    0,    0,  211,    0,    0,    0,    0,    0,    0,
+    0,  102,  211,  211,    0,    0,    0,    0,    0,    0,
+    0,    0,  211,  211,    0,  211,    0,    0,    0,    0,
+    0,  211,  211,  211,    0,    0,  211,    0,  211,  211,
+    0,  211,    0,    0,    0,    0,    0,    0,    0,  211,
+  211,    0,  212,    0,  102,    0,    0,    0,    0,  211,
+  211,    0,  211,    0,    0,    0,    0,    0,  212,    0,
+    0,  212,  212,    0,    0,    0,    0,  211,    0,    0,
+  212,  212,  212,    0,    0,    0,    0,    0,  211,  212,
+    0,  212,  212,    0,  212,    0,  212,    0,    0,    0,
+  212,  212,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,  212,    0,    0,    0,    0,    0,    0,
+    0,    0,  212,  212,    0,    0,    0,    0,    0,    0,
+    0,    0,  212,  212,  103,  212,  211,    0,    0,    0,
+    0,  212,  212,  212,    0,    0,  212,    0,  212,  212,
+  103,  212,    0,  103,  103,    0,    0,    0,    0,  212,
+  212,    0,  103,  103,  103,    0,    0,    0,    0,  212,
+  212,  103,  212,  103,    0,    0,  103,    0,  103,    0,
+    0,    0,  103,  103,    0,    0,    0,  212,    0,    0,
+    0,    0,    0,    0,    0,  103,    0,    0,  212,    0,
+    0,    0,    0,    0,  103,  103,    0,    0,    0,    0,
+    0,    0,    0,    0,  103,  103,    0,  103,    0,  138,
+    0,    0,    0,  103,  103,  103,    0,    0,  103,  103,
+  103,  103,    0,  103,    0,  138,    0,    0,  138,  138,
+    0,  103,  103,    0,    0,    0,  212,  138,  138,  138,
+    0,  103,  103,    0,  103,    0,  138,    0,  138,    0,
+    0,  138,    0,  138,    0,    0,    0,  138,  138,  103,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  138,    0,    0,    0,    0,  103,    0,    0,    0,  138,
+  138,    0,    0,    0,    0,    0,    0,    0,    0,  138,
+  138,  227,  138,    0,    0,    0,    0,    0,  138,  138,
+  138,    0,    0,  138,  138,  138,  138,  227,  138,    0,
+  227,  227,    0,    0,    0,    0,  138,  138,  103,  227,
+  227,  227,    0,    0,    0,    0,  138,  138,  227,  138,
+  227,    0,    0,  227,    0,  227,    0,    0,    0,  227,
+  227,    0,    0,    0,  138,    0,    0,    0,    0,    0,
+    0,    0,  227,    0,    0,    0,    0,    0,    0,    0,
+  138,  227,  227,    0,    0,    0,    0,    0,    0,    0,
+    0,  227,  227,    0,  227,    0,  174,    0,    0,    0,
+  227,  227,  227,    0,    0,  227,  227,  227,  227,    0,
+  227,    0,  174,    0,    0,  174,  174,    0,  227,  227,
+    0,    0,    0,  138,  174,  174,  174,    0,  227,  227,
+    0,  227,    0,  174,    0,  174,    0,    0,  174,    0,
+  174,    0,    0,    0,  174,  174,  227,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  174,    0,    0,
+    0,    0,  227,    0,    0,    0,  174,  174,    0,    0,
+    0,    0,    0,    0,    0,    0,  174,  174,  235,  174,
+    0,    0,    0,    0,    0,  174,  174,  174,    0,    0,
+  174,  174,  174,  174,  235,  174,    0,  235,  235,    0,
+    0,    0,    0,  174,  174,  227,  235,  235,  235,    0,
+    0,    0,    0,  174,  174,  235,  174,  235,    0,    0,
+  235,    0,  235,    0,    0,    0,  235,  235,    0,    0,
+    0,  174,    0,    0,    0,    0,    0,    0,    0,  235,
+    0,    0,    0,    0,    0,    0,    0,  174,  235,  235,
+    0,    0,    0,    0,    0,    0,    0,    0,  235,  235,
+    0,  235,    0,  206,    0,    0,    0,  235,  235,  235,
+    0,    0,  235,  235,  235,  235,    0,  235,    0,  206,
+    0,    0,  206,  206,    0,  235,  235,    0,    0,    0,
+  174,  206,  206,  206,    0,  235,  235,    0,  235,    0,
+  206,    0,  206,    0,    0,  206,    0,  206,    0,    0,
+    0,  206,  206,  235,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,  206,    0,    0,    0,    0,  235,
+    0,    0,    0,  206,  206,    0,    0,    0,    0,    0,
+    0,    0,    0,  206,  206,  154,  206,    0,    0,    0,
+    0,    0,  206,  206,  206,    0,    0,  206,  206,  206,
+  206,  154,  206,    0,  154,  154,    0,    0,    0,    0,
+  206,  206,  235,  154,  154,  154,    0,    0,    0,    0,
+  206,  206,  154,  206,  154,    0,    0,  154,    0,  154,
+    0,    0,    0,  154,  154,    0,    0,    0,  206,    0,
+    0,    0,    0,    0,    0,    0,  154,    0,    0,    0,
+    0,    0,    0,    0,  206,  154,  154,    0,    0,    0,
+    0,    0,    0,    0,    0,  154,  154,    0,  154,    0,
+  157,    0,    0,    0,  154,  154,  154,    0,    0,  154,
+  154,  154,  154,    0,  154,    0,  157,    0,    0,  157,
+  157,    0,  154,  154,    0,    0,    0,  206,  157,  157,
+  157,    0,  154,  154,    0,  154,    0,  157,    0,  157,
+    0,    0,  157,    0,  157,    0,    0,    0,  157,  157,
+  154,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,  157,    0,    0,    0,    0,  154,    0,    0,    0,
+  157,  157,    0,    0,    0,    0,    0,    0,    0,    0,
+  157,  157,   58,  157,    0,    0,    0,    0,    0,  157,
+  157,  157,    0,    0,  157,  157,  157,  157,   58,  157,
+    0,   58,   58,    0,    0,    0,    0,  157,  157,  154,
+   58,   58,   58,    0,    0,    0,    0,  157,  157,  125,
+  157,   58,    0,    0,   58,    0,   58,    0,    0,    0,
+   58,   58,    0,    0,    0,  157,    0,    0,    0,    0,
+    0,    0,    0,   58,    0,    0,    0,    0,    0,    0,
+    0,  157,   58,   58,    0,    0,    0,    0,    0,    0,
+    0,    0,   58,   58,    0,   58,    0,   58,    0,    0,
+    0,   58,   58,   58,    0,    0,   58,   58,   58,   58,
+    0,   58,    0,   58,    0,    0,   58,   58,    0,   58,
+   58,    0,    0,    0,  157,   58,   58,   58,    0,   58,
+   58,    0,   58,    0,  126,    0,   58,    0,    0,   58,
+    0,   58,    0,    0,    0,   58,   58,   58,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,   58,    0,
+    0,    0,    0,    0,    0,    0,    0,   58,   58,    0,
+    0,    0,    0,    0,    0,    0,    0,   58,   58,  210,
+   58,    0,    0,    0,    0,    0,   58,   58,   58,    0,
+    0,   58,   58,   58,   58,  210,   58,    0,  210,  210,
+    0,    0,    0,    0,   58,   58,   58,  210,  210,  210,
+    0,    0,    0,    0,   58,   58,  210,   58,  210,  210,
+    0,  210,    0,  210,    0,    0,    0,  210,  210,    0,
+    0,    0,   58,    0,    0,    0,    0,    0,    0,    0,
+  210,    0,    0,    0,    0,    0,    0,    0,    0,  210,
+  210,    0,    0,    0,    0,    0,    0,    0,    0,  210,
+  210,    0,  210,    0,   58,    0,    0,    0,  210,  210,
+  210,    0,    0,  210,    0,  210,  210,    0,  210,    0,
+   58,    0,    0,   58,   58,    0,  210,  210,    0,    0,
+    0,   58,   58,   58,   58,    0,  210,  210,    0,  210,
+    0,  139,    0,   58,    0,    0,   58,    0,   58,    0,
+    0,    0,   58,   58,  210,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,   58,    0,    0,    0,    0,
+    0,    0,    0,    0,   58,   58,    0,    0,    0,    0,
+    0,    0,    0,    0,   58,   58,   58,   58,    0,    0,
+    0,    0,    0,   58,   58,   58,    0,    0,   58,   58,
+   58,   58,   58,   58,    0,   58,   58,    0,    0,    0,
+    0,   58,   58,  210,   58,   58,   58,    0,    0,    0,
+    0,   58,   58,  140,   58,   58,    0,    0,   58,    0,
+   58,    0,    0,    0,   58,   58,    0,    0,    0,   58,
+    0,    0,    0,    0,    0,    0,    0,   58,    0,    0,
+    0,    0,    0,    0,    0,    0,   58,   58,    0,    0,
+    0,    0,    0,  470,  470,    0,   58,   58,    0,   58,
+    0,  209,    0,    0,    0,   58,   58,   58,    0,    0,
+   58,   58,   58,   58,    0,   58,    0,  209,    0,    0,
+  209,  209,    0,   58,   58,    0,    0,    0,   58,  209,
+  209,  209,    0,   58,   58,    0,   58,    0,  209,  470,
+  209,    0,    0,  209,    0,  209,    0,    0,    0,  209,
+  209,   58,    0,    0,    0,  470,    0,    0,    0,    0,
+    0,  470,  209,    0,    0,    0,  480,  480,  470,    0,
+    0,  209,  209,    0,    0,    0,    0,    0,    0,    0,
+    0,  209,  209,    0,  209,    0,  470,  470,    0,    0,
+  209,  209,  209,    0,    0,  209,    0,  209,  209,    0,
+  209,    0,    0,    0,    0,    0,    0,    0,  209,  209,
+   58,    0,  480,    0,    0,    0,  385,  385,  209,  209,
+  470,  209,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,  480,  470,  209,    0,    0,    0,
+  470,  480,  470,  470,    0,  470,  470,  470,  470,  470,
+  470,  470,  470,  470,  470,    0,  470,  470,    0,  480,
+  480,    0,  385,    0,    0,    0,    0,  470,    0,  470,
+    0,  470,    0,    0,    0,  470,    0,  470,    0,    0,
+    0,    0,    0,    0,  385,    0,    0,    0,    0,  362,
+  362,  385,    0,  480,    0,  209,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  480,  385,
+  385,    0,    0,  480,    0,  480,  480,  480,  480,  480,
+  480,  480,  480,  480,  480,  480,  480,  480,    0,  480,
+  480,    0,    0,    0,    0,  362,    0,    0,    0,    0,
+  480,    0,  480,  385,  480,    0,    0,    0,  480,    0,
+  480,    0,    0,    0,    0,    0,    0,  362,  385,    0,
+    0,    0,    0,  384,  362,  385,  385,  384,  385,  385,
+  385,  385,  385,  385,  385,  385,  385,  385,    0,  385,
+  385,    0,  362,  362,    0,    0,  319,  319,    0,    0,
+  385,    0,  385,    0,  385,    0,    0,    0,  385,    0,
+  385,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  362,    0,    0,    0,
+    0,    0,    0,    0,  415,  415,    0,    0,    0,    0,
+    0,  362,  319,    0,    0,    0,  362,    0,  362,  362,
+    0,  362,  362,  362,  362,  362,  362,  362,  362,  362,
+  362,    0,  362,  362,  319,    0,    0,    0,    0,    0,
+    0,  319,    0,  362,    0,  362,    0,  362,    0,    0,
+  415,  362,    0,  362,    0,    0,    0,    0,    0,  319,
+  319,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,  415,    0,    0,    0,    0,    0,    0,  415,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,  319,    0,    0,    0,  415,  415,    0,
+    0,  416,  416,    0,    0,    0,    0,    0,  319,    0,
+    0,    0,    0,    0,    0,  319,  319,  319,  319,  319,
+  319,  319,  319,  319,  319,  319,  319,  319,    0,  319,
+  319,  415,    0,    0,    0,    0,    0,    0,    0,    0,
+  319,    0,  319,    0,  319,    0,  415,  416,  319,    0,
+  319,  417,  417,  415,  415,    0,  415,  415,  415,  415,
+  415,  415,  415,  415,  415,  415,    0,  415,  415,  416,
+    0,    0,    0,    0,    0,    0,  416,    0,  415,    0,
+  415,    0,  415,    0,    0,    0,  415,    0,  415,    0,
+    0,    0,    0,    0,  416,  416,    0,  417,   44,   44,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,  417,
+    0,    0,    0,    0,    0,    0,  417,    0,  416,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,  416,  417,  417,    0,    0,  423,  423,
+  416,  416,    0,  416,  416,  416,  416,  416,  416,  416,
+  416,  416,  416,    0,  416,  416,   44,    0,    0,    0,
+    0,    0,    0,   44,    0,  416,    0,  416,  417,  416,
+    0,    0,    0,  416,    0,  416,    0,    0,    0,    0,
+    0,   44,   44,  417,  423,    0,    0,    0,  424,  424,
+  417,  417,    0,  417,  417,  417,  417,  417,  417,  417,
+  417,  417,    0,    0,  417,  417,  423,    0,    0,    0,
+    0,    0,    0,  423,    0,  417,    0,  417,    0,  417,
+    0,    0,    0,  417,    0,  417,    0,    0,    0,    0,
+   44,  423,  423,    0,  424,   44,    0,    0,   44,   44,
+   44,    0,   44,   44,   44,   44,   44,   44,   44,   44,
+    0,   44,   44,    0,    0,    0,  424,    0,    0,    0,
+  425,  425,   44,  424,   44,  423,   44,    0,    0,    0,
+   44,    0,   44,    0,    0,    0,    0,    0,    0,    0,
+  423,  424,  424,    0,    0,    0,    0,  423,  423,    0,
+  423,  423,  423,  423,  423,  423,  423,    0,    0,    0,
+    0,  423,  423,  426,  426,    0,  425,    0,    0,    0,
+    0,    0,  423,    0,  423,  424,  423,    0,    0,    0,
+  423,    0,  423,    0,    0,    0,    0,    0,  425,    0,
+  424,    0,    0,    0,    0,  425,    0,  424,  424,    0,
+  424,  424,  424,  424,  424,  424,  424,    0,    0,  426,
+    0,  424,  424,  425,  425,  427,  427,    0,    0,    0,
+    0,    0,  424,    0,  424,    0,  424,    0,    0,    0,
+  424,  426,  424,    0,    0,    0,    0,    0,  426,    0,
+    0,    0,    0,    0,    0,    0,    0,  425,    0,    0,
+    0,    0,    0,    0,    0,    0,  426,  426,    0,    0,
+    0,  427,  425,    0,    0,  428,  428,    0,    0,  425,
+  425,    0,  425,  425,  425,  425,  425,  425,  425,    0,
+    0,    0,    0,  427,  425,    0,    0,    0,    0,    0,
+  426,    0,    0,    0,  425,    0,  425,    0,  425,    0,
+    0,    0,  425,    0,  425,  426,    0,    0,  427,  427,
+    0,  428,  426,  426,    0,  426,  426,  426,  426,  426,
+  426,  426,    0,    0,    0,    0,    0,  426,    0,    0,
+    0,    0,    0,  428,  429,  429,    0,  426,    0,  426,
+    0,  426,  427,    0,    0,  426,    0,  426,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,  427,  428,  428,
+    0,    0,    0,    0,  427,  427,    0,  427,  427,  427,
+  427,  427,  427,  427,    0,    0,    0,    0,    0,  427,
+  429,    0,    0,    0,  430,  430,    0,    0,    0,  427,
+    0,  427,  428,  427,    0,    0,    0,  427,    0,  427,
+    0,    0,  429,    0,    0,    0,    0,  428,    0,    0,
+    0,    0,    0,    0,  428,  428,    0,  428,  428,  428,
+  428,  428,  428,  428,    0,    0,    0,  429,  429,  428,
+  430,    0,    0,    0,  431,  431,    0,    0,    0,  428,
+    0,  428,    0,  428,    0,    0,    0,  428,    0,  428,
+    0,    0,  430,    0,    0,    0,    0,    0,    0,    0,
+    0,  429,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  429,  430,  430,    0,
+  431,    0,    0,  429,  429,    0,  429,  429,  429,  429,
+  429,  429,  429,    0,    0,    0,    0,    0,  429,    0,
+    0,    0,  431,  432,  432,    0,    0,    0,  429,    0,
+  429,  430,  429,    0,    0,    0,  429,    0,  429,    0,
+    0,    0,    0,    0,    0,    0,  430,  431,  431,    0,
+    0,    0,    0,  430,  430,    0,  430,  430,    0,    0,
+  430,  430,  430,    0,    0,    0,    0,    0,  430,  432,
+    0,    0,    0,  433,  433,    0,    0,    0,  430,    0,
+  430,  431,  430,    0,    0,    0,  430,    0,  430,    0,
+    0,  432,    0,    0,    0,    0,  431,    0,    0,    0,
+    0,    0,    0,  431,  431,    0,  431,  431,    0,    0,
+  431,  431,  431,    0,    0,    0,  432,  432,  431,  433,
+    0,    0,    0,  434,  434,    0,    0,    0,  431,    0,
+  431,    0,  431,    0,    0,    0,  431,    0,  431,    0,
+    0,  433,    0,    0,    0,    0,    0,    0,    0,    0,
+  432,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+  435,  435,    0,    0,    0,  432,  433,  433,    0,  434,
+    0,    0,  432,  432,    0,  432,  432,    0,    0,  432,
+  432,  432,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,  434,    0,    0,    0,  480,  480,  432,    0,  432,
+  433,  432,    0,    0,    0,  432,  435,  432,    0,    0,
+    0,    0,    0,    0,    0,  433,  434,  434,    0,    0,
+    0,    0,  433,  433,    0,  433,  433,    0,  435,  433,
+  433,  433,  442,  442,    0,    0,    0,    0,    0,    0,
+    0,  480,    0,    0,    0,    0,    0,  433,    0,  433,
+  434,  433,    0,  435,  435,  433,    0,  433,    0,    0,
+    0,    0,    0,  480,    0,  434,    0,    0,    0,    0,
+    0,    0,  434,  434,    0,  434,  434,    0,  442,  434,
+  434,  434,  436,  436,    0,    0,    0,  435,  480,  480,
+    0,    0,    0,    0,    0,    0,    0,  434,    0,  434,
+  442,  434,  435,    0,    0,  434,    0,  434,    0,  435,
+  435,    0,  435,  435,    0,    0,  435,  435,  435,  438,
+  438,    0,  480,    0,    0,  442,  442,    0,  436,    0,
+    0,    0,  439,  439,  435,    0,  435,  480,  435,    0,
+    0,    0,    0,    0,  480,  480,    0,  480,  480,    0,
+  436,  480,  480,  480,    0,    0,    0,    0,    0,  442,
+    0,    0,    0,    0,    0,  438,    0,    0,    0,  480,
+    0,  480,    0,  480,  442,  436,  436,    0,  439,    0,
+    0,  442,  442,    0,  442,  442,    0,  438,  442,  442,
+  442,    0,    0,    0,    0,    0,    0,    0,  440,  440,
+  439,    0,    0,    0,    0,    0,  442,    0,  442,  436,
+  442,    0,  438,  438,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,  436,  439,  439,    0,    0,    0,
+    0,  436,  436,    0,  436,  436,    0,    0,  436,  436,
+  436,  441,  441,    0,  440,    0,  438,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,  436,    0,  436,  439,
+  436,  438,    0,    0,    0,    0,  440,    0,  438,  438,
+    0,  438,  438,    0,  439,  438,  438,  438,    0,    0,
+    0,  439,  439,    0,  439,  439,    0,  441,  439,  439,
+  439,  440,  440,  438,    0,  438,    0,  438,    0,    0,
+    0,    0,    0,    0,    0,    0,  439,    0,  439,  441,
+  439,  437,  437,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,  440,    0,    0,    0,    0,
+    0,    0,    0,    0,  441,  441,    0,    0,    0,    0,
+  440,    0,    0,    0,    0,    0,    0,  440,  440,    0,
+  440,  440,    0,    0,  440,  440,  440,  437,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  441,    0,
+    0,    0,  440,    0,  440,    0,  440,    0,    0,  437,
+    0,    0,    0,  441,    0,    0,    0,    0,    0,    0,
+  441,  441,    0,  441,  441,    0,    0,  441,  441,  441,
+    0,    0,    0,    0,  437,  437,    0,    0,    0,    0,
+    0,   21,    0,    0,    0,  441,    0,  441,    0,  441,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,  437,   21,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,   21,   21,  437,    0,    0,    0,    0,    0,    0,
+  437,  437,   21,  437,  437,    0,    0,  437,  437,  437,
+    0,   21,    0,    0,    0,    0,    0,    0,    0,    0,
+   21,    0,    0,   19,   21,  437,    0,  437,    0,  437,
+    0,    0,    0,   21,   21,    0,    0,    0,   21,    0,
+    0,    0,    0,   21,   21,    0,    0,    0,   21,    0,
+    0,   19,   21,   21,   21,    0,    0,   21,    0,   21,
+   21,    0,   21,   19,   19,    0,    0,    0,    0,    0,
+   21,   21,    0,    0,   19,    0,    0,    0,    0,    0,
+   21,    0,    0,   19,    0,    0,    0,    0,    0,    0,
+    0,    0,   19,    0,    0,   20,   19,    0,   21,    0,
+    0,    0,    0,    0,    0,   19,   19,    0,    0,    0,
+   19,    0,    0,    0,   21,   19,   19,    0,    0,    0,
+   19,    0,    0,   20,   19,   19,   19,    0,    0,   19,
+    0,   19,   19,    0,   19,   20,   20,    0,    0,    0,
+    0,    0,   19,   19,    0,    0,   20,    0,    0,    0,
+    0,    0,   19,    0,    0,   20,    0,    0,    0,    0,
+    0,    0,    0,    0,   20,    0,    0,    7,   20,    0,
+   19,    0,    0,    0,    0,    0,    0,   20,   20,    0,
+    0,    0,   20,    0,    0,    0,   19,   20,   20,    0,
+    0,    0,   20,    0,    0,    7,   20,   20,   20,    0,
+    0,   20,    0,   20,   20,    0,   20,    7,    7,    0,
+    0,    0,    0,    0,   20,   20,    0,    0,    7,    0,
+    0,    0,    0,    0,   20,    0,    0,    7,    0,    0,
+    0,    0,    0,    0,    0,    0,    7,    0,    0,    8,
+    7,    0,   20,    0,    0,    0,    0,    0,    0,    7,
+    7,    0,    0,    0,    7,    0,    0,    0,   20,    7,
+    7,    0,    0,    0,    0,    0,    0,    8,    7,    7,
+    7,    0,    0,    7,    0,    7,    7,    0,    7,    8,
+    8,    0,    0,    0,    0,    0,    7,    7,    0,    0,
+    8,    0,    0,    0,    0,    0,    7,    0,    0,    8,
+    0,    0,    0,    0,    0,    0,    0,    0,    8,    0,
+    0,   50,    8,    0,    7,    0,    0,    0,    0,    0,
+    0,    8,    8,    0,    0,    0,    8,    0,    0,    0,
+    7,    8,    8,    0,    0,    0,    0,    0,    0,   50,
+    8,    8,    8,    0,    0,    8,    0,    8,    8,    0,
+    8,   50,   50,    0,    0,    0,    0,    0,    8,    8,
+    0,    0,   50,    0,    0,    0,    0,    0,    8,    0,
+    0,   50,    0,    0,    0,    0,    0,    0,    0,    0,
+   50,    0,    0,   89,   50,    0,    8,    0,    0,    0,
+    0,    0,    0,   50,   50,    0,    0,    0,   50,    0,
+    0,    0,    8,   50,   50,    0,    0,    0,    0,    0,
+    0,   89,   50,   50,   50,    0,    0,   50,    0,   50,
+   50,    0,   50,   89,   89,    0,    0,    0,    0,    0,
+   50,   50,   89,    0,   89,    0,    0,    0,    0,    0,
+   50,    0,    0,   89,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,   46,   89,    0,   50,    0,
+    0,    0,    0,    0,    0,   89,   89,    0,    0,    0,
+   89,    0,    0,    0,   50,   89,   89,    0,    0,    0,
+    0,    0,    0,   46,   89,   89,   89,    0,    0,   89,
+    0,   89,   89,    0,   89,   46,   46,    0,    0,    0,
+    0,    0,   89,   89,    0,    0,   46,    0,    0,    0,
+    0,    0,   89,    0,    0,   46,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,   47,   46,    0,
+   89,    0,    0,    0,    0,    0,    0,   46,   46,    0,
+    0,    0,   46,    0,    0,    0,   89,   46,   46,    0,
+    0,    0,    0,    0,    0,   47,   46,   46,   46,    0,
+    0,   46,    0,   46,   46,    0,   46,   47,   47,    0,
+    0,    0,    0,    0,   46,   46,    0,    0,   47,    0,
+    0,    0,    0,    0,   46,    0,    0,   47,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+   47,    0,   46,    0,    0,    0,    0,    0,    0,   47,
+   47,    0,    0,    0,   47,    0,    0,    0,   46,   47,
+   47,    0,    0,    0,    0,    0,    0,   88,   47,   47,
+   47,    0,    0,   47,    0,   47,   47,    0,   47,   88,
+   88,    0,    0,    0,    0,    0,   47,   47,   88,    0,
+   88,    0,    0,    0,    0,    0,   47,    0,    0,   88,
+    0,    0,    0,    0,    0,    0,    0,    0,  185,    0,
+    0,    0,   88,    0,   47,    0,    0,  185,    0,    0,
+    0,   88,   88,    0,    0,    0,   88,    0,  185,  185,
+   47,   88,   88,    0,    0,    0,    0,    0,    0,  185,
+   88,   88,   88,    0,    0,   88,    0,   88,   88,    0,
+   88,  185,    0,    0,    0,    0,    0,    0,   88,   88,
+  185,  185,    0,    0,    0,    0,    0,    0,   88,  185,
+  185,  185,    0,  193,  185,  185,  185,  185,    0,  185,
+    0,    0,  193,    0,    0,    0,   88,  185,  185,    0,
+    0,    0,    0,  193,  193,    0,    0,    0,  185,    0,
+    0,    0,   88,  189,  193,    0,    0,    0,    0,    0,
+    0,    0,  189,    0,    0,  185,  193,    0,    0,    0,
+    0,    0,    0,  189,  189,  193,  193,    0,    0,    0,
+    0,  185,    0,    0,  193,  193,  193,    0,  190,  193,
+  193,  193,  193,    0,  193,    0,  189,  190,    0,    0,
+    0,    0,  193,  193,    0,  189,  189,    0,  190,  190,
+    0,    0,    0,  193,  189,  189,  189,    0,  202,  189,
+  189,  189,  189,    0,  189,    0,    0,  202,    0,    0,
+  193,  190,  189,  189,    0,    0,    0,    0,  202,  202,
+  190,  190,    0,  189,    0,    0,  193,    0,    0,  190,
+  190,  190,    0,  203,  190,  190,  190,  190,    0,  190,
+  189,  202,  203,    0,    0,    0,    0,  190,  190,    0,
+  202,  202,    0,  203,  203,    0,  189,    0,  190,  202,
+  202,  202,    0,  184,  202,  202,  202,  202,    0,  202,
+    0,    0,  184,    0,    0,  190,  203,  202,  202,    0,
+    0,    0,    0,  184,  184,  203,  203,    0,  202,    0,
+    0,  190,    0,    0,  203,  203,  203,    0,    0,  203,
+  203,  203,  203,    0,  203,  202,  184,    0,    0,    0,
+    0,    0,  203,  203,    0,  184,  184,    0,    0,    0,
+    0,  202,    0,  203,  184,  184,  184,    0,    0,  184,
+  184,  184,  184,    0,  184,    0,   58,    0,    0,    0,
+  203,    0,  184,  184,    0,    0,    0,    0,   58,   58,
+    0,    0,    0,  184,    0,    0,  203,   22,    0,   58,
+    0,    0,    0,    0,    0,    0,    0,    0,   58,    0,
+  184,    0,    0,    0,    0,    0,   58,    0,    0,    0,
+    0,   58,    0,    0,    0,    0,  184,    0,   58,   58,
+   58,   58,    0,    0,    0,   58,    0,   23,    0,   58,
+   58,   58,    0,    0,    0,    0,    0,    0,   58,   58,
+   58,   58,    0,    0,   58,    0,   58,   58,    0,   58,
+    0,   58,    0,    0,    0,    0,    0,   58,   58,    0,
+   58,   58,    0,    0,    0,   58,    0,   58,    0,    0,
+   58,   58,    0,    0,    0,    0,    0,    0,   58,   58,
+   58,   58,    0,    0,   58,   58,   58,   58,    0,   58,
+   58,   58,    0,    0,    0,    0,    0,   58,   58,    0,
+    0,   58,    0,    0,    0,    0,    0,   58,    0,    0,
+   58,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,   58,    0,   58,    0,    0,    0,    0,
+    0,    0,   58,   58,    0,    0,    0,   58,    0,    0,
+    0,    0,   58,   58,    0,    0,    0,    0,    0,    0,
+    0,   58,   58,   58,    0,    0,   58,    0,   58,   58,
+    0,   58,    0,    0,    0,    0,    0,    0,    0,   58,
+   58,    0,    0,    0,    0,    0,    0,    0,    0,   58,
+    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+    0,    0,    0,    0,    0,    0,    0,   58,
+  };
+  protected static  short [] yyCheck = {            73,
+    0,  306,  188,   24,  188,   56,   23,  313,  466,  257,
+  601,  324,  318,  266,  269,  256,  266,  407,  306,  266,
+  309,  165,  269,  306,  288,  325,  410,  306,  266,  449,
+   30,  309,  266,   33,   34,   56,  267,  449,  269,  314,
+  319,  288,  197,  198,  372,   23,  319,  266,  289,  313,
+  266,  594,   52,  269,  306,  410,  319,  288,  309,  414,
+   77,   78,  269,  304,  305,  306,  313,  253,  659,  253,
+  398,  309,  288,  269,  665,  459,  262,   55,  262,  266,
+  623,  288,  313,  324,  266,  309,  544,  375,  546,  326,
+  309,  309,  288,  146,  189,  331,  516,  313,   76,  306,
+   78,  309,  375,  615,  516,  352,  313,  407,  339,  354,
+  306,  128,  375,  130,  131,  132,  133,  313,  393,  309,
+  384,  352,  309,  375,  309,  414,  415,  282,  283,  146,
+  520,  414,  420,  319,  389,  319,  352,  281,  325,  156,
+  157,  420,  389,  196,  122,  352,  269,  309,  126,  309,
+  463,  269,  269,  266,  154,  155,  352,  309,  389,  159,
+  160,  161,  415,  413,  415,  288,  413,  407,  680,  627,
+  288,  288,  420,  389,  360,  153,  410,  266,  690,  413,
+  420,  415,  389,  306,  574,  419,  372,  699,  306,  780,
+  313,  410,  416,  389,  309,  313,  313,  415,  384,  385,
+  384,  385,  592,  298,  299,  796,  718,  260,  261,  445,
+  188,  447,  398,  420,  604,  605,  463,  309,  309,  272,
+  309,  274,  463,  410,  420,  415,  416,  280,  345,  352,
+  415,  413,  463,  415,  352,  352,  541,  419,  449,  271,
+  635,  273,  637,  309,  430,  318,  430,  463,  449,  269,
+  449,  352,  353,  415,  254,  415,  463,  274,  275,  325,
+  277,  278,  414,  309,  416,  285,  389,  463,  288,  289,
+  309,  389,  389,  326,  327,  253,  410,  269,  298,  299,
+  414,  676,  303,  420,  262,  309,  591,  308,  308,  310,
+  802,  311,  804,  313,  309,  309,  288,  463,  318,  694,
+  413,  416,  415,  609,  419,  516,  419,  358,  422,  423,
+  330,  354,  449,  266,  387,  516,  309,  516,  309,  339,
+  309,  313,  414,  355,  344,  416,  415,  416,  269,  361,
+  419,  412,  352,  311,  415,  547,  415,  358,  309,  269,
+  463,  319,  421,  319,  364,  463,  463,  288,  560,  370,
+  536,  368,  536,  539,  325,  539,  309,  378,  288,  269,
+  352,  271,  757,  273,  407,  760,  386,  387,  420,  389,
+  416,  269,  313,  271,  769,  273,  415,  416,  288,  516,
+  419,  413,  360,  313,  570,  419,  570,  404,  309,  695,
+  288,  415,  416,  414,  372,  419,  396,  389,  309,  375,
+  309,  416,  416,  313,  799,  795,  384,  385,  309,  409,
+  410,  352,  433,  413,  325,  313,  318,  459,  615,  410,
+  398,  816,  352,  416,  415,  416,  447,  416,  419,  429,
+  309,  306,  432,  309,  487,  452,  436,  454,  455,  456,
+  315,  419,  352,  463,  420,  355,  325,  419,  389,  466,
+  450,  361,  430,   38,  352,  476,   41,  355,  415,  389,
+  615,  306,  364,  361,  421,  271,  519,  273,  698,  318,
+  625,  463,  414,  690,  319,  492,  631,  390,  445,  389,
+  447,   66,  699,  680,   23,  387,  269,  270,  488,  272,
+  720,  389,  407,  690,  415,  416,  309,  309,  419,  413,
+  283,  718,  699,  413,  504,  288,  420,  415,  525,  526,
+  527,  511,  295,  417,  418,  364,   55,  534,  571,  302,
+  344,  718,  463,  523,  309,  680,  413,  544,  415,  546,
+  313,  309,  585,  463,  413,  690,  415,   76,  387,   78,
+  419,  594,  542,  276,  699,  306,  329,  777,  548,  355,
+  306,  309,  335,  463,  315,  361,  786,  557,  536,  315,
+  790,  539,  345,  718,  309,  463,  566,  449,  351,  352,
+  623,  304,  305,  306,  410,  713,  629,  807,  390,  632,
+  633,  634,  315,  122,  266,  802,  724,  804,  774,  589,
+  774,  821,  570,  405,  416,  378,  379,  671,  598,  413,
+  412,  413,  385,  415,  416,  802,  389,  804,  266,  626,
+  627,  749,  309,  630,  153,  410,  616,  617,  618,  413,
+  620,  415,  263,  264,  624,  410,  272,  309,  274,  414,
+  683,  416,  417,  418,  419,  263,  264,  422,  423,  424,
+  410,  309,  427,  325,  356,  357,  276,  802,  510,  804,
+  703,  704,  705,  331,  707,  708,  709,  710,  711,  712,
+  445,  414,  447,  269,  413,  414,  719,  410,  309,  722,
+  691,  809,  435,  811,  304,  305,  306,  413,  540,  285,
+  463,  414,  288,  289,  415,  315,  286,  287,  356,  357,
+  269,  415,  298,  299,  503,  716,  717,  309,  413,  508,
+  415,  414,  308,  565,  419,  311,  285,  313,  725,  288,
+  289,  309,  318,  787,  405,  356,  357,  770,  410,  298,
+  299,  424,  390,  532,  330,  587,  266,  306,  426,  308,
+  289,  290,  311,  339,  313,  300,  301,  405,  427,  318,
+  740,  419,  420,  421,  412,  413,  352,  415,  416,  390,
+  338,  330,  463,  573,  563,  564,  410,  410,  364,  437,
+  339,  439,  762,  441,  405,  782,  766,  767,  410,  309,
+  413,  412,  413,  352,  415,  416,  328,  328,  390,  779,
+  386,  387,  602,  389,  414,  325,  415,  413,  608,  304,
+  305,  306,  390,  405,  614,  415,  774,  797,  413,  415,
+  412,  413,  413,  415,  416,  306,  325,  386,  387,  413,
+  389,  413,  415,  257,  412,  413,  260,  415,  416,  304,
+  305,  306,  306,  823,  824,  269,  270,  271,  272,  273,
+  274,  415,  276,  277,  278,  279,  413,  281,  282,  283,
+  284,  285,  286,  287,  288,  289,  290,  291,  292,  293,
+  413,  295,  344,  297,  298,  299,  300,  463,  302,  306,
+  304,  305,  306,  339,  308,  413,  413,  311,  308,  313,
+  314,  315,  306,  317,  318,  319,  320,  410,  322,  306,
+  324,  419,  415,  416,  463,  329,  330,  410,  421,  306,
+  266,  335,  195,  337,  266,  339,  340,  410,  342,  343,
+  344,  345,  285,  386,  348,  349,  350,  351,  352,  419,
+  330,  355,  410,  325,  358,  359,  360,  361,  413,  363,
+  364,  365,  366,  367,  368,  413,  413,  371,  410,  373,
+  475,  375,  376,  377,  378,  379,  415,  415,  269,  410,
+  415,  385,  386,  387,  388,  389,  415,  391,  261,  393,
+  394,  413,  414,  415,  285,  376,  419,  288,  289,  419,
+  404,  382,  413,  414,  415,  419,  410,  298,  299,  419,
+  414,  419,  261,  417,  418,  306,  420,  308,  419,  276,
+  311,  419,  313,  413,  414,  415,  257,  318,  291,  292,
+  293,  294,  295,  296,  297,  419,  306,  306,  269,  330,
+  271,  422,  273,  413,  306,  449,  387,  451,  339,  453,
+  306,  455,  285,  457,  285,  459,  285,  288,  289,  463,
+  285,  352,  410,  444,  364,  298,  297,  298,  299,  298,
+  375,  319,  388,  298,  266,  308,  394,  308,  387,  308,
+  311,  324,  313,  308,  306,  306,  317,  318,  319,  306,
+  318,  394,  413,  474,  306,  386,  387,  330,  389,  330,
+  324,  330,  306,  319,  324,  330,  339,  375,  339,  340,
+  339,  344,  306,  344,  339,  344,  324,  414,  349,  350,
+  309,  352,  309,  309,  355,  413,  413,  358,  359,  360,
+  361,  413,  363,  364,  365,  366,  257,  368,  413,  413,
+  419,  413,  309,  309,  375,  376,  377,  309,  269,  413,
+  271,  303,  273,  386,    8,  386,  387,  386,  389,   15,
+   25,  386,   78,  111,  285,  122,  302,  288,  289,  274,
+  107,  275,  463,  404,  516,  378,  297,  298,  299,  158,
+  626,  476,  422,  309,  374,  370,  588,  308,  447,  420,
+  311,  717,  313,  627,  716,  765,  317,  318,  319,  429,
+  430,  431,  432,  433,  434,  405,  408,  634,  680,  330,
+  727,  770,  534,  813,  544,  514,  393,  521,  339,  340,
+  284,  257,  285,  344,  279,   -1,  288,   -1,  349,  350,
+   -1,  352,  463,  269,  355,   -1,   -1,  358,  359,  360,
+  361,   -1,  363,  364,  365,  366,   -1,  368,   -1,  285,
+   -1,   -1,  288,  289,  375,  376,  377,   -1,   -1,   -1,
+   -1,  297,  298,  299,   -1,  386,  387,   -1,  389,   -1,
+  306,   -1,  308,   -1,   -1,  311,   -1,  313,   -1,   -1,
+   -1,  317,  318,  404,  410,   -1,   -1,   -1,  414,   -1,
+  416,  417,  418,  419,  330,   -1,  422,  423,  424,  420,
+   -1,  427,   -1,  339,  340,  257,   -1,   -1,  344,   -1,
+   -1,   -1,   -1,  349,  350,   -1,  352,  269,   -1,  445,
+   -1,  447,  358,  359,  360,   -1,   -1,  363,  364,  365,
+  366,   -1,  368,  285,   -1,   -1,  288,  289,   -1,   -1,
+  376,  377,  463,   -1,   -1,  297,  298,  299,   -1,   -1,
+  386,  387,   -1,  389,  306,   -1,  308,   -1,   -1,  311,
+   -1,  313,   -1,   -1,   -1,  317,  318,   -1,  404,   -1,
+   -1,   -1,   -1,   -1,   -1,  417,  418,  419,  330,   -1,
+  422,  423,  424,   -1,  420,  427,   -1,  339,  340,  257,
+   -1,   -1,  344,   -1,   -1,   -1,   -1,  349,  350,   -1,
+  352,  269,   -1,  445,   -1,  447,  358,  359,  360,   -1,
+   -1,  363,  364,  365,  366,   -1,  368,  285,   -1,   -1,
+  288,  289,   -1,   -1,  376,  377,   -1,  463,   -1,  297,
+  298,  299,   -1,   -1,  386,  387,   -1,  389,  306,   -1,
+  308,   -1,   -1,  311,   -1,  313,   -1,   -1,   -1,  317,
+  318,   -1,  404,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  330,   -1,   -1,   -1,   -1,   -1,  420,   -1,
+   -1,  339,  340,  257,   -1,   -1,  344,   -1,   -1,   -1,
+   -1,  349,  350,   -1,  352,  269,   -1,   -1,   -1,   -1,
+  358,  359,  360,   -1,   -1,  363,  364,  365,  366,   -1,
+  368,  285,   -1,   -1,  288,  289,   -1,   -1,  376,  377,
+   -1,  463,   -1,  297,  298,  299,   -1,   -1,  386,  387,
+   -1,  389,  306,   -1,  308,   -1,   -1,  311,   -1,  313,
+   -1,   -1,   -1,  317,  318,   -1,  404,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  330,   -1,   -1,   -1,
+   -1,   -1,  420,   -1,   -1,  339,  340,  257,   -1,   -1,
+  344,   -1,   -1,   -1,   -1,  349,  350,   -1,  352,  269,
+   -1,   -1,   -1,   -1,  358,  359,  360,   -1,   -1,  363,
+  364,  365,  366,   -1,  368,  285,   -1,   -1,  288,  289,
+   -1,   -1,  376,  377,   -1,  463,   -1,  297,  298,  299,
+   -1,   -1,  386,  387,   -1,  389,  306,   -1,  308,   -1,
+   -1,  311,   -1,  313,   -1,   -1,   -1,  317,  318,   -1,
+  404,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  330,   -1,   -1,   -1,   -1,   -1,  420,   -1,   -1,  339,
+  340,  257,   -1,   -1,  344,   -1,   -1,   -1,   -1,  349,
+  350,   -1,  352,  269,   -1,   -1,   -1,   -1,  358,  359,
+  360,   -1,   -1,  363,  364,  365,  366,   -1,  368,  285,
+   -1,   -1,  288,  289,   -1,   -1,  376,  377,   -1,  463,
+   -1,  297,  298,  299,   -1,   -1,  386,  387,   -1,  389,
+  306,   -1,  308,   -1,   -1,  311,   -1,  313,   -1,   -1,
+   -1,  317,  318,   -1,  404,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  330,   -1,   -1,   -1,   -1,   -1,
+  420,   -1,   -1,  339,  340,  257,   -1,   -1,  344,   -1,
+   -1,   -1,   -1,  349,  350,   -1,  352,  269,   -1,   -1,
+   -1,   -1,  358,  359,  360,   -1,   -1,  363,  364,  365,
+  366,   -1,  368,  285,   -1,   -1,  288,  289,   -1,   -1,
+  376,  377,   -1,  463,   -1,  297,  298,  299,   -1,   -1,
+  386,  387,   -1,  389,  306,   -1,  308,   -1,   -1,  311,
+   -1,  313,   -1,   -1,   -1,  317,  318,   -1,  404,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  330,   -1,
+   -1,   -1,   -1,   -1,  420,   -1,   -1,  339,  340,   -1,
+   -1,   -1,  344,   -1,   -1,   -1,   -1,  349,  350,   -1,
+  352,   -1,   -1,   -1,   -1,   -1,  358,  359,  360,   -1,
+   -1,  363,  364,  365,  366,   -1,  368,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  376,  377,   -1,  463,   -1,   -1,
+   -1,   -1,  260,   -1,  386,  387,   -1,  389,   -1,   -1,
+   -1,  269,  270,   -1,  272,   -1,  274,   -1,   -1,  277,
+  278,  279,  404,  281,  282,  283,  284,   -1,  286,  287,
+  288,  289,  290,  291,  292,  293,   -1,  295,  420,   -1,
+   -1,  299,  300,   -1,  302,   -1,   -1,   -1,  306,   -1,
+   -1,   -1,   -1,   -1,   -1,  313,  314,   -1,   -1,   -1,
+   -1,   -1,  320,   -1,  322,   -1,  324,   -1,   -1,   -1,
+  309,  329,  269,  270,   -1,  272,   -1,  335,   -1,  337,
+   -1,  463,   -1,   -1,  342,  343,  283,  345,   -1,   -1,
+  348,  288,   -1,  351,  352,   -1,   -1,   -1,  295,   -1,
+   -1,   -1,   -1,   -1,   -1,  302,   -1,   -1,   -1,  367,
+   -1,   -1,   -1,  371,   -1,  373,  313,  356,  357,   -1,
+  378,  379,   -1,   -1,   -1,   -1,   -1,  385,   -1,   -1,
+  388,  389,  329,  391,   -1,  393,  394,   -1,  335,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  390,  410,   -1,  351,  352,  414,   -1,   -1,  417,
+  418,   -1,   -1,   -1,   -1,   -1,  405,   -1,   -1,   -1,
+   -1,   -1,   -1,  412,  413,   -1,  415,  416,   -1,   -1,
+   -1,  378,  379,   -1,  309,   -1,   -1,   -1,  385,   -1,
+   -1,  449,  389,  451,  260,  453,   -1,  455,   -1,  457,
+   -1,  459,   -1,  269,  270,  463,  272,   -1,  274,   -1,
+   -1,  277,  278,  279,   -1,  281,  282,  283,  284,   -1,
+  286,  287,  288,  289,  290,  291,  292,  293,   -1,  295,
+   -1,  356,  357,  299,  300,   -1,  302,   -1,   -1,   -1,
+  306,   -1,   -1,   -1,   -1,   -1,   -1,  313,  314,   -1,
+   -1,   -1,   -1,   -1,  320,   -1,  322,   -1,  324,   -1,
+   -1,   -1,   -1,  329,   -1,  390,  463,   -1,   -1,  335,
+   -1,  337,   -1,   -1,   -1,   -1,  342,  343,   -1,  345,
+  405,   -1,  348,   -1,   -1,  351,  352,  412,  413,   -1,
+  415,  416,   -1,   -1,  297,   -1,   -1,   -1,   -1,   -1,
+   -1,  367,   -1,  306,   -1,  371,   -1,  373,   -1,   -1,
+   -1,   -1,  378,  379,  317,  318,   -1,   -1,   -1,  385,
+   -1,   -1,  388,  389,   -1,  391,   -1,  393,  394,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  340,   -1,   -1,
+   -1,   -1,   -1,   -1,  410,   -1,  349,  350,  414,   -1,
+   -1,  417,  418,   -1,   -1,  358,  359,  360,   -1,   -1,
+  363,  364,  365,  366,   -1,  368,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  376,  377,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  449,  387,  451,  260,  453,   -1,  455,
+   -1,  457,   -1,  459,   -1,  269,  270,  463,  272,   -1,
+  274,  404,   -1,  277,  278,  279,   -1,  281,  282,  283,
+  284,   -1,  286,  287,  288,  289,  290,  291,  292,  293,
+   -1,  295,   -1,   -1,   -1,  299,  300,   -1,  302,   -1,
+   -1,  285,  306,   -1,   -1,  289,   -1,   -1,   -1,  313,
+  314,   -1,   -1,   -1,  298,  299,  320,   -1,  322,   -1,
+  324,   -1,   -1,   -1,  308,  329,   -1,  311,   -1,   -1,
+   -1,  335,   -1,  337,  318,   -1,   -1,   -1,  342,  343,
+   -1,  345,   -1,   -1,  348,   -1,  330,  351,  352,   -1,
+   -1,   -1,   -1,   -1,   -1,  339,  297,   -1,   -1,   -1,
+   -1,   -1,   -1,  367,   -1,  306,   -1,  371,   -1,  373,
+   -1,   -1,   -1,   -1,  378,  379,  317,  318,   -1,   -1,
+  364,  385,   -1,   -1,  388,  389,   -1,  391,   -1,  393,
+  394,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  340,
+   -1,   -1,  386,  387,   -1,   -1,  410,   -1,  349,  350,
+  414,   -1,   -1,  417,  418,   -1,   -1,  358,  359,  360,
+   -1,   -1,  363,  364,  365,  366,   -1,  368,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  376,  377,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  449,  387,  451,  260,  453,
+   -1,  455,   -1,  457,   -1,  459,   -1,  269,  270,  463,
+  272,   -1,  274,  404,   -1,  277,  278,  279,   -1,  281,
+  282,  283,  284,   -1,  286,  287,  288,  289,  290,  291,
+  292,  293,   -1,  295,   -1,   -1,   -1,  299,  300,   -1,
+  302,   -1,   -1,  285,  306,   -1,   -1,  289,   -1,   -1,
+   -1,  313,  314,   -1,   -1,   -1,  298,  299,  320,   -1,
+  322,   -1,  324,   -1,   -1,   -1,  308,  329,   -1,  311,
+   -1,   -1,   -1,  335,   -1,  337,  318,   -1,   -1,   -1,
+  342,  343,   -1,  345,   -1,   -1,  348,   -1,  330,  351,
+  352,   -1,   -1,   -1,   -1,   -1,   -1,  339,  297,   -1,
+   -1,   -1,   -1,   -1,   -1,  367,   -1,   -1,   -1,  371,
+   -1,  373,   -1,   -1,   -1,   -1,  378,  379,  317,   -1,
+   -1,   -1,   -1,  385,   -1,   -1,  388,  389,   -1,  391,
+   -1,  393,  394,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  340,   -1,   -1,  386,  387,   -1,   -1,  410,   -1,
+  349,  350,  414,   -1,   -1,  417,  418,   -1,   -1,  358,
+  359,  360,   -1,   -1,  363,   -1,  365,  366,   -1,  368,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  376,  377,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  449,   -1,  451,
+  260,  453,   -1,  455,   -1,  457,   -1,  459,   -1,  269,
+  270,  463,  272,   -1,  274,  404,   -1,  277,  278,  279,
+   -1,  281,  282,  283,  284,   -1,  286,  287,  288,  289,
+  290,  291,  292,  293,   -1,  295,   -1,   -1,   -1,  299,
+  300,   -1,  302,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  313,  314,   -1,   -1,   -1,   -1,   -1,
+  320,   -1,  322,   -1,  324,   -1,   -1,   -1,   -1,  329,
+   -1,   -1,   -1,   -1,   -1,  335,   -1,  337,   -1,   -1,
+   -1,   -1,  342,  343,   -1,  345,   -1,   -1,  348,   -1,
+   -1,  351,  352,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  367,   -1,   -1,
+   -1,  371,   -1,  373,   -1,   -1,   -1,   -1,  378,  379,
+   -1,   -1,   -1,   -1,   -1,  385,   -1,   -1,  388,  389,
+   -1,  391,   -1,  393,  394,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  410,   -1,   -1,  261,   -1,   -1,   -1,  417,  418,   -1,
+   -1,  269,  270,  271,  272,   -1,  274,   -1,   -1,  277,
+  278,  279,   -1,  281,  282,  283,  284,   -1,  286,  287,
+  288,   -1,  290,  291,  292,  293,   -1,  295,   -1,  449,
+   -1,  451,  300,  453,  302,  455,   -1,  457,   -1,  459,
+   -1,   -1,   -1,  463,   -1,  313,  314,   -1,   -1,   -1,
+   -1,   -1,  320,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  329,   -1,   -1,   -1,   -1,   -1,  335,   -1,  337,
+   -1,   -1,   -1,   -1,  342,  343,   -1,  345,   -1,  347,
+  348,   -1,   -1,  351,  352,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  378,  379,   -1,   -1,   -1,   -1,   -1,  385,   -1,   -1,
+   -1,  389,   -1,   -1,   -1,  393,   -1,  395,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  410,   -1,   -1,  261,   -1,   -1,   -1,  417,
+  418,   -1,   -1,  269,  270,   -1,  272,   -1,  274,   -1,
+   -1,  277,  278,  279,   -1,  281,  282,  283,  284,   -1,
+  286,  287,  288,   -1,  290,  291,  292,  293,   -1,  295,
+   -1,  449,   -1,  451,  300,  453,  302,  455,   -1,  457,
+   -1,  459,   -1,   -1,   -1,  463,   -1,  313,  314,   -1,
+   -1,   -1,   -1,   -1,  320,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  329,   -1,   -1,   -1,   -1,   -1,  335,
+   -1,  337,   -1,   -1,   -1,   -1,  342,  343,   -1,  345,
+   -1,  347,  348,   -1,   -1,  351,  352,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  378,  379,   -1,   -1,   -1,   -1,   -1,  385,
+   -1,   -1,   -1,  389,   -1,   -1,   -1,  393,   -1,  395,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  410,   -1,   -1,   -1,   -1,   -1,
+   -1,  417,  418,   -1,   -1,  269,  270,   -1,  272,   -1,
+  274,   -1,   -1,  277,  278,  279,   -1,  281,  282,  283,
+  284,   -1,  286,  287,  288,   -1,  290,  291,  292,  293,
+   -1,  295,   -1,  449,   -1,  451,  300,  453,  302,  455,
+   -1,  457,   -1,  459,   -1,   -1,   -1,  463,   -1,  313,
+  314,   -1,   -1,   -1,   -1,   -1,  320,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  329,   -1,   -1,   -1,   -1,
+   -1,  335,   -1,  337,   -1,   -1,   -1,   -1,  342,  343,
+   -1,  345,   -1,  347,  348,   -1,   -1,  351,  352,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  378,  379,   -1,   -1,   -1,   -1,
+   -1,  385,   -1,   -1,   -1,  389,   -1,   -1,   -1,  393,
+   -1,  395,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  410,  411,  412,   -1,
+   -1,   -1,   -1,  417,  418,   -1,   -1,  269,  270,   -1,
+  272,   -1,  274,   -1,   -1,  277,  278,  279,   -1,  281,
+  282,  283,  284,   -1,  286,  287,  288,   -1,  290,  291,
+  292,  293,   -1,  295,   -1,  449,   -1,  451,  300,  453,
+  302,  455,   -1,  457,   -1,  459,   -1,   -1,   -1,  463,
+   -1,  313,  314,   -1,   -1,   -1,   -1,   -1,  320,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  329,   -1,   -1,
+   -1,   -1,   -1,  335,   -1,  337,   -1,   -1,   -1,   -1,
+  342,  343,   -1,  345,   -1,  347,  348,   -1,   -1,  351,
+  352,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  378,  379,   -1,   -1,
+   -1,   -1,   -1,  385,   -1,   -1,   -1,  389,   -1,   -1,
+   -1,  393,   -1,  395,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  410,  411,
+   -1,   -1,   -1,   -1,   -1,  417,  418,   -1,   -1,  269,
+  270,   -1,  272,   -1,  274,   -1,   -1,  277,  278,  279,
+   -1,  281,  282,  283,  284,   -1,  286,  287,  288,   -1,
+  290,  291,  292,  293,   -1,  295,   -1,  449,   -1,  451,
+  300,  453,  302,  455,   -1,  457,   -1,  459,   -1,   -1,
+   -1,  463,   -1,  313,  314,   -1,   -1,   -1,   -1,   -1,
+  320,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  329,
+   -1,   -1,   -1,   -1,   -1,  335,   -1,  337,   -1,   -1,
+   -1,   -1,  342,  343,   -1,  345,   -1,  347,  348,   -1,
+   -1,  351,  352,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  378,  379,
+   -1,   -1,   -1,   -1,   -1,  385,   -1,   -1,   -1,  389,
+   -1,   -1,   -1,  393,   -1,  395,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  410,   -1,   -1,   -1,   -1,   -1,  257,  417,  418,   -1,
+   -1,  269,  270,   -1,  272,   -1,  274,   -1,   -1,  277,
+  278,  279,   -1,  281,  282,  283,  284,   -1,  286,  287,
+  288,   -1,  290,  291,  292,  293,   -1,  295,   -1,  449,
+   -1,  451,  300,  453,  302,  455,  297,  457,   -1,  459,
+   -1,   -1,   -1,  463,   -1,  313,  314,   -1,   -1,   -1,
+   -1,   -1,  320,   -1,   -1,   -1,  317,   -1,   -1,   -1,
+   -1,  329,   -1,   -1,   -1,   -1,   -1,  335,   -1,  337,
+   -1,   -1,   -1,   -1,  342,  343,   -1,  345,   -1,  340,
+  348,   -1,   -1,  351,  352,   -1,   -1,   -1,  349,  350,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  358,  359,  360,
+   -1,   -1,  363,   -1,  365,  366,   -1,  368,   -1,   -1,
+  378,  379,   -1,   -1,   -1,  376,  377,  385,   -1,   -1,
+   -1,  389,   -1,   -1,   -1,  393,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  410,  404,   -1,   -1,   -1,   -1,   -1,  417,
+  418,   -1,   -1,  269,  270,   -1,  272,   -1,  274,   -1,
+   -1,  277,  278,  279,   -1,  281,  282,  283,  284,   -1,
+  286,  287,  288,   -1,  290,  291,  292,  293,   -1,  295,
+   -1,  449,   -1,  451,  300,  453,  302,  455,   -1,  457,
+   -1,  459,   -1,   -1,   -1,  463,   -1,  313,  314,   -1,
+   -1,   -1,   -1,   -1,  320,  257,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  329,   -1,   -1,   -1,   -1,   -1,  335,
+   -1,  337,   -1,   -1,   -1,   -1,  342,  343,   -1,  345,
+   -1,   -1,  348,  285,   -1,  351,  352,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  297,  298,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  308,   -1,   -1,   -1,
+   -1,   -1,  378,  379,   -1,  317,   -1,   -1,   -1,  385,
+   -1,   -1,   -1,  389,   -1,   -1,   -1,  393,  330,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  339,  340,   -1,
+   -1,   -1,  344,   -1,  410,   -1,   -1,  349,  350,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  358,  359,  360,   -1,
+   -1,  363,   -1,  365,  366,   -1,  368,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  376,  377,  269,   -1,   -1,   -1,
+   -1,   -1,   -1,  449,  386,  451,   -1,  453,   -1,  455,
+   -1,  457,  285,  459,   -1,  288,  289,  463,   -1,   -1,
+   -1,   -1,  404,   -1,  297,  298,  299,   -1,   -1,   -1,
+   -1,   -1,   -1,  306,   -1,  308,   -1,   -1,  311,   -1,
+  313,   -1,   -1,   -1,  317,  318,   -1,   -1,   -1,   -1,
+   -1,   -1,  325,   -1,   -1,  328,   -1,  330,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  339,  340,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  349,  350,  269,  352,
+   -1,   -1,   -1,   -1,   -1,  358,  359,  360,   -1,   -1,
+  363,  364,  365,  366,  285,  368,   -1,  288,  289,   -1,
+   -1,   -1,   -1,  376,  377,   -1,  297,  298,  299,   -1,
+   -1,   -1,   -1,  386,  387,  306,  389,  308,   -1,   -1,
+  311,   -1,  313,   -1,   -1,   -1,  317,  318,   -1,   -1,
+   -1,  404,   -1,   -1,  325,   -1,   -1,   -1,   -1,  330,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  420,  339,  340,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  349,  350,
+   -1,  352,   -1,  269,   -1,   -1,   -1,  358,  359,  360,
+   -1,   -1,  363,  364,  365,  366,   -1,  368,   -1,  285,
+   -1,   -1,  288,  289,   -1,  376,  377,   -1,   -1,   -1,
+  463,  297,  298,  299,   -1,  386,  387,   -1,  389,   -1,
+  306,   -1,  308,   -1,   -1,  311,   -1,  313,   -1,   -1,
+   -1,  317,  318,  404,   -1,   -1,   -1,   -1,   -1,  325,
+   -1,   -1,   -1,   -1,  330,   -1,   -1,   -1,   -1,  420,
+   -1,   -1,   -1,  339,  340,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  349,  350,  269,  352,   -1,   -1,   -1,
+   -1,   -1,  358,  359,  360,   -1,   -1,  363,  364,  365,
+  366,  285,  368,   -1,  288,  289,   -1,   -1,   -1,   -1,
+  376,  377,  463,  297,  298,  299,   -1,   -1,   -1,   -1,
+  386,  387,  306,  389,  308,   -1,   -1,  311,   -1,  313,
+   -1,   -1,   -1,  317,  318,   -1,   -1,   -1,  404,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  330,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  420,  339,  340,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  349,  350,   -1,  352,   -1,
+  269,   -1,   -1,   -1,  358,  359,  360,   -1,   -1,  363,
+  364,  365,  366,   -1,  368,   -1,  285,   -1,   -1,  288,
+  289,   -1,  376,  377,   -1,   -1,   -1,  463,  297,  298,
+  299,   -1,  386,  387,   -1,  389,   -1,  306,   -1,  308,
+   -1,   -1,  311,   -1,  313,   -1,   -1,   -1,  317,  318,
+  404,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  330,   -1,   -1,   -1,   -1,  420,   -1,   -1,   -1,
+  339,  340,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  349,  350,  269,  352,   -1,   -1,   -1,   -1,   -1,  358,
+  359,  360,   -1,   -1,  363,  364,  365,  366,  285,  368,
+   -1,  288,  289,   -1,   -1,   -1,   -1,  376,  377,  463,
+  297,  298,  299,   -1,   -1,   -1,   -1,  386,  387,  306,
+  389,  308,  309,   -1,  311,   -1,  313,   -1,   -1,   -1,
+  317,  318,   -1,   -1,   -1,  404,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  330,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  420,  339,  340,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  349,  350,   -1,  352,   -1,   -1,   -1,   -1,
+   -1,  358,  359,  360,   -1,   -1,  363,   -1,  365,  366,
+   -1,  368,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  376,
+  377,   -1,  269,   -1,  463,   -1,   -1,   -1,   -1,  386,
+  387,   -1,  389,   -1,   -1,   -1,   -1,   -1,  285,   -1,
+   -1,  288,  289,   -1,   -1,   -1,   -1,  404,   -1,   -1,
+  297,  298,  299,   -1,   -1,   -1,   -1,   -1,  415,  306,
+   -1,  308,  309,   -1,  311,   -1,  313,   -1,   -1,   -1,
+  317,  318,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  330,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  339,  340,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  349,  350,  269,  352,  463,   -1,   -1,   -1,
+   -1,  358,  359,  360,   -1,   -1,  363,   -1,  365,  366,
+  285,  368,   -1,  288,  289,   -1,   -1,   -1,   -1,  376,
+  377,   -1,  297,  298,  299,   -1,   -1,   -1,   -1,  386,
+  387,  306,  389,  308,   -1,   -1,  311,   -1,  313,   -1,
+   -1,   -1,  317,  318,   -1,   -1,   -1,  404,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  330,   -1,   -1,  415,   -1,
+   -1,   -1,   -1,   -1,  339,  340,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  349,  350,   -1,  352,   -1,  269,
+   -1,   -1,   -1,  358,  359,  360,   -1,   -1,  363,  364,
+  365,  366,   -1,  368,   -1,  285,   -1,   -1,  288,  289,
+   -1,  376,  377,   -1,   -1,   -1,  463,  297,  298,  299,
+   -1,  386,  387,   -1,  389,   -1,  306,   -1,  308,   -1,
+   -1,  311,   -1,  313,   -1,   -1,   -1,  317,  318,  404,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  330,   -1,   -1,   -1,   -1,  420,   -1,   -1,   -1,  339,
+  340,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  349,
+  350,  269,  352,   -1,   -1,   -1,   -1,   -1,  358,  359,
+  360,   -1,   -1,  363,  364,  365,  366,  285,  368,   -1,
+  288,  289,   -1,   -1,   -1,   -1,  376,  377,  463,  297,
+  298,  299,   -1,   -1,   -1,   -1,  386,  387,  306,  389,
+  308,   -1,   -1,  311,   -1,  313,   -1,   -1,   -1,  317,
+  318,   -1,   -1,   -1,  404,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  330,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  420,  339,  340,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  349,  350,   -1,  352,   -1,  269,   -1,   -1,   -1,
+  358,  359,  360,   -1,   -1,  363,  364,  365,  366,   -1,
+  368,   -1,  285,   -1,   -1,  288,  289,   -1,  376,  377,
+   -1,   -1,   -1,  463,  297,  298,  299,   -1,  386,  387,
+   -1,  389,   -1,  306,   -1,  308,   -1,   -1,  311,   -1,
+  313,   -1,   -1,   -1,  317,  318,  404,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  330,   -1,   -1,
+   -1,   -1,  420,   -1,   -1,   -1,  339,  340,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  349,  350,  269,  352,
+   -1,   -1,   -1,   -1,   -1,  358,  359,  360,   -1,   -1,
+  363,  364,  365,  366,  285,  368,   -1,  288,  289,   -1,
+   -1,   -1,   -1,  376,  377,  463,  297,  298,  299,   -1,
+   -1,   -1,   -1,  386,  387,  306,  389,  308,   -1,   -1,
+  311,   -1,  313,   -1,   -1,   -1,  317,  318,   -1,   -1,
+   -1,  404,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  330,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  420,  339,  340,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  349,  350,
+   -1,  352,   -1,  269,   -1,   -1,   -1,  358,  359,  360,
+   -1,   -1,  363,  364,  365,  366,   -1,  368,   -1,  285,
+   -1,   -1,  288,  289,   -1,  376,  377,   -1,   -1,   -1,
+  463,  297,  298,  299,   -1,  386,  387,   -1,  389,   -1,
+  306,   -1,  308,   -1,   -1,  311,   -1,  313,   -1,   -1,
+   -1,  317,  318,  404,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  330,   -1,   -1,   -1,   -1,  420,
+   -1,   -1,   -1,  339,  340,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  349,  350,  269,  352,   -1,   -1,   -1,
+   -1,   -1,  358,  359,  360,   -1,   -1,  363,  364,  365,
+  366,  285,  368,   -1,  288,  289,   -1,   -1,   -1,   -1,
+  376,  377,  463,  297,  298,  299,   -1,   -1,   -1,   -1,
+  386,  387,  306,  389,  308,   -1,   -1,  311,   -1,  313,
+   -1,   -1,   -1,  317,  318,   -1,   -1,   -1,  404,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  330,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  420,  339,  340,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  349,  350,   -1,  352,   -1,
+  269,   -1,   -1,   -1,  358,  359,  360,   -1,   -1,  363,
+  364,  365,  366,   -1,  368,   -1,  285,   -1,   -1,  288,
+  289,   -1,  376,  377,   -1,   -1,   -1,  463,  297,  298,
+  299,   -1,  386,  387,   -1,  389,   -1,  306,   -1,  308,
+   -1,   -1,  311,   -1,  313,   -1,   -1,   -1,  317,  318,
+  404,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  330,   -1,   -1,   -1,   -1,  420,   -1,   -1,   -1,
+  339,  340,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  349,  350,  269,  352,   -1,   -1,   -1,   -1,   -1,  358,
+  359,  360,   -1,   -1,  363,  364,  365,  366,  285,  368,
+   -1,  288,  289,   -1,   -1,   -1,   -1,  376,  377,  463,
+  297,  298,  299,   -1,   -1,   -1,   -1,  386,  387,  306,
+  389,  308,   -1,   -1,  311,   -1,  313,   -1,   -1,   -1,
+  317,  318,   -1,   -1,   -1,  404,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  330,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  420,  339,  340,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  349,  350,   -1,  352,   -1,  269,   -1,   -1,
+   -1,  358,  359,  360,   -1,   -1,  363,  364,  365,  366,
+   -1,  368,   -1,  285,   -1,   -1,  288,  289,   -1,  376,
+  377,   -1,   -1,   -1,  463,  297,  298,  299,   -1,  386,
+  387,   -1,  389,   -1,  306,   -1,  308,   -1,   -1,  311,
+   -1,  313,   -1,   -1,   -1,  317,  318,  404,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  330,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  339,  340,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  349,  350,  269,
+  352,   -1,   -1,   -1,   -1,   -1,  358,  359,  360,   -1,
+   -1,  363,  364,  365,  366,  285,  368,   -1,  288,  289,
+   -1,   -1,   -1,   -1,  376,  377,  463,  297,  298,  299,
+   -1,   -1,   -1,   -1,  386,  387,  306,  389,  308,  309,
+   -1,  311,   -1,  313,   -1,   -1,   -1,  317,  318,   -1,
+   -1,   -1,  404,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  330,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  339,
+  340,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  349,
+  350,   -1,  352,   -1,  269,   -1,   -1,   -1,  358,  359,
+  360,   -1,   -1,  363,   -1,  365,  366,   -1,  368,   -1,
+  285,   -1,   -1,  288,  289,   -1,  376,  377,   -1,   -1,
+   -1,  463,  297,  298,  299,   -1,  386,  387,   -1,  389,
+   -1,  306,   -1,  308,   -1,   -1,  311,   -1,  313,   -1,
+   -1,   -1,  317,  318,  404,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  330,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  339,  340,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  349,  350,  269,  352,   -1,   -1,
+   -1,   -1,   -1,  358,  359,  360,   -1,   -1,  363,  364,
+  365,  366,  285,  368,   -1,  288,  289,   -1,   -1,   -1,
+   -1,  376,  377,  463,  297,  298,  299,   -1,   -1,   -1,
+   -1,  386,  387,  306,  389,  308,   -1,   -1,  311,   -1,
+  313,   -1,   -1,   -1,  317,  318,   -1,   -1,   -1,  404,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  330,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  339,  340,   -1,   -1,
+   -1,   -1,   -1,  263,  264,   -1,  349,  350,   -1,  352,
+   -1,  269,   -1,   -1,   -1,  358,  359,  360,   -1,   -1,
+  363,  364,  365,  366,   -1,  368,   -1,  285,   -1,   -1,
+  288,  289,   -1,  376,  377,   -1,   -1,   -1,  463,  297,
+  298,  299,   -1,  386,  387,   -1,  389,   -1,  306,  309,
+  308,   -1,   -1,  311,   -1,  313,   -1,   -1,   -1,  317,
+  318,  404,   -1,   -1,   -1,  325,   -1,   -1,   -1,   -1,
+   -1,  331,  330,   -1,   -1,   -1,  263,  264,  338,   -1,
+   -1,  339,  340,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  349,  350,   -1,  352,   -1,  356,  357,   -1,   -1,
+  358,  359,  360,   -1,   -1,  363,   -1,  365,  366,   -1,
+  368,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  376,  377,
+  463,   -1,  309,   -1,   -1,   -1,  263,  264,  386,  387,
+  390,  389,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  331,  405,  404,   -1,   -1,   -1,
+  410,  338,  412,  413,   -1,  415,  416,  417,  418,  419,
+  420,  421,  422,  423,  424,   -1,  426,  427,   -1,  356,
+  357,   -1,  309,   -1,   -1,   -1,   -1,  437,   -1,  439,
+   -1,  441,   -1,   -1,   -1,  445,   -1,  447,   -1,   -1,
+   -1,   -1,   -1,   -1,  331,   -1,   -1,   -1,   -1,  263,
+  264,  338,   -1,  390,   -1,  463,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  405,  356,
+  357,   -1,   -1,  410,   -1,  412,  413,  414,  415,  416,
+  417,  418,  419,  420,  421,  422,  423,  424,   -1,  426,
+  427,   -1,   -1,   -1,   -1,  309,   -1,   -1,   -1,   -1,
+  437,   -1,  439,  390,  441,   -1,   -1,   -1,  445,   -1,
+  447,   -1,   -1,   -1,   -1,   -1,   -1,  331,  405,   -1,
+   -1,   -1,   -1,  410,  338,  412,  413,  414,  415,  416,
+  417,  418,  419,  420,  421,  422,  423,  424,   -1,  426,
+  427,   -1,  356,  357,   -1,   -1,  263,  264,   -1,   -1,
+  437,   -1,  439,   -1,  441,   -1,   -1,   -1,  445,   -1,
+  447,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  390,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  263,  264,   -1,   -1,   -1,   -1,
+   -1,  405,  309,   -1,   -1,   -1,  410,   -1,  412,  413,
+   -1,  415,  416,  417,  418,  419,  420,  421,  422,  423,
+  424,   -1,  426,  427,  331,   -1,   -1,   -1,   -1,   -1,
+   -1,  338,   -1,  437,   -1,  439,   -1,  441,   -1,   -1,
+  309,  445,   -1,  447,   -1,   -1,   -1,   -1,   -1,  356,
+  357,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  331,   -1,   -1,   -1,   -1,   -1,   -1,  338,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  390,   -1,   -1,   -1,  356,  357,   -1,
+   -1,  263,  264,   -1,   -1,   -1,   -1,   -1,  405,   -1,
+   -1,   -1,   -1,   -1,   -1,  412,  413,  414,  415,  416,
+  417,  418,  419,  420,  421,  422,  423,  424,   -1,  426,
+  427,  390,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  437,   -1,  439,   -1,  441,   -1,  405,  309,  445,   -1,
+  447,  263,  264,  412,  413,   -1,  415,  416,  417,  418,
+  419,  420,  421,  422,  423,  424,   -1,  426,  427,  331,
+   -1,   -1,   -1,   -1,   -1,   -1,  338,   -1,  437,   -1,
+  439,   -1,  441,   -1,   -1,   -1,  445,   -1,  447,   -1,
+   -1,   -1,   -1,   -1,  356,  357,   -1,  309,  263,  264,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  331,
+   -1,   -1,   -1,   -1,   -1,   -1,  338,   -1,  390,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  405,  356,  357,   -1,   -1,  263,  264,
+  412,  413,   -1,  415,  416,  417,  418,  419,  420,  421,
+  422,  423,  424,   -1,  426,  427,  331,   -1,   -1,   -1,
+   -1,   -1,   -1,  338,   -1,  437,   -1,  439,  390,  441,
+   -1,   -1,   -1,  445,   -1,  447,   -1,   -1,   -1,   -1,
+   -1,  356,  357,  405,  309,   -1,   -1,   -1,  263,  264,
+  412,  413,   -1,  415,  416,  417,  418,  419,  420,  421,
+  422,  423,   -1,   -1,  426,  427,  331,   -1,   -1,   -1,
+   -1,   -1,   -1,  338,   -1,  437,   -1,  439,   -1,  441,
+   -1,   -1,   -1,  445,   -1,  447,   -1,   -1,   -1,   -1,
+  405,  356,  357,   -1,  309,  410,   -1,   -1,  413,  414,
+  415,   -1,  417,  418,  419,  420,  421,  422,  423,  424,
+   -1,  426,  427,   -1,   -1,   -1,  331,   -1,   -1,   -1,
+  263,  264,  437,  338,  439,  390,  441,   -1,   -1,   -1,
+  445,   -1,  447,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  405,  356,  357,   -1,   -1,   -1,   -1,  412,  413,   -1,
+  415,  416,  417,  418,  419,  420,  421,   -1,   -1,   -1,
+   -1,  426,  427,  263,  264,   -1,  309,   -1,   -1,   -1,
+   -1,   -1,  437,   -1,  439,  390,  441,   -1,   -1,   -1,
+  445,   -1,  447,   -1,   -1,   -1,   -1,   -1,  331,   -1,
+  405,   -1,   -1,   -1,   -1,  338,   -1,  412,  413,   -1,
+  415,  416,  417,  418,  419,  420,  421,   -1,   -1,  309,
+   -1,  426,  427,  356,  357,  263,  264,   -1,   -1,   -1,
+   -1,   -1,  437,   -1,  439,   -1,  441,   -1,   -1,   -1,
+  445,  331,  447,   -1,   -1,   -1,   -1,   -1,  338,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  390,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  356,  357,   -1,   -1,
+   -1,  309,  405,   -1,   -1,  263,  264,   -1,   -1,  412,
+  413,   -1,  415,  416,  417,  418,  419,  420,  421,   -1,
+   -1,   -1,   -1,  331,  427,   -1,   -1,   -1,   -1,   -1,
+  390,   -1,   -1,   -1,  437,   -1,  439,   -1,  441,   -1,
+   -1,   -1,  445,   -1,  447,  405,   -1,   -1,  356,  357,
+   -1,  309,  412,  413,   -1,  415,  416,  417,  418,  419,
+  420,  421,   -1,   -1,   -1,   -1,   -1,  427,   -1,   -1,
+   -1,   -1,   -1,  331,  263,  264,   -1,  437,   -1,  439,
+   -1,  441,  390,   -1,   -1,  445,   -1,  447,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  405,  356,  357,
+   -1,   -1,   -1,   -1,  412,  413,   -1,  415,  416,  417,
+  418,  419,  420,  421,   -1,   -1,   -1,   -1,   -1,  427,
+  309,   -1,   -1,   -1,  263,  264,   -1,   -1,   -1,  437,
+   -1,  439,  390,  441,   -1,   -1,   -1,  445,   -1,  447,
+   -1,   -1,  331,   -1,   -1,   -1,   -1,  405,   -1,   -1,
+   -1,   -1,   -1,   -1,  412,  413,   -1,  415,  416,  417,
+  418,  419,  420,  421,   -1,   -1,   -1,  356,  357,  427,
+  309,   -1,   -1,   -1,  263,  264,   -1,   -1,   -1,  437,
+   -1,  439,   -1,  441,   -1,   -1,   -1,  445,   -1,  447,
+   -1,   -1,  331,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  390,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  405,  356,  357,   -1,
+  309,   -1,   -1,  412,  413,   -1,  415,  416,  417,  418,
+  419,  420,  421,   -1,   -1,   -1,   -1,   -1,  427,   -1,
+   -1,   -1,  331,  263,  264,   -1,   -1,   -1,  437,   -1,
+  439,  390,  441,   -1,   -1,   -1,  445,   -1,  447,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  405,  356,  357,   -1,
+   -1,   -1,   -1,  412,  413,   -1,  415,  416,   -1,   -1,
+  419,  420,  421,   -1,   -1,   -1,   -1,   -1,  427,  309,
+   -1,   -1,   -1,  263,  264,   -1,   -1,   -1,  437,   -1,
+  439,  390,  441,   -1,   -1,   -1,  445,   -1,  447,   -1,
+   -1,  331,   -1,   -1,   -1,   -1,  405,   -1,   -1,   -1,
+   -1,   -1,   -1,  412,  413,   -1,  415,  416,   -1,   -1,
+  419,  420,  421,   -1,   -1,   -1,  356,  357,  427,  309,
+   -1,   -1,   -1,  263,  264,   -1,   -1,   -1,  437,   -1,
+  439,   -1,  441,   -1,   -1,   -1,  445,   -1,  447,   -1,
+   -1,  331,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  390,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  263,  264,   -1,   -1,   -1,  405,  356,  357,   -1,  309,
+   -1,   -1,  412,  413,   -1,  415,  416,   -1,   -1,  419,
+  420,  421,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  331,   -1,   -1,   -1,  263,  264,  437,   -1,  439,
+  390,  441,   -1,   -1,   -1,  445,  309,  447,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  405,  356,  357,   -1,   -1,
+   -1,   -1,  412,  413,   -1,  415,  416,   -1,  331,  419,
+  420,  421,  263,  264,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  309,   -1,   -1,   -1,   -1,   -1,  437,   -1,  439,
+  390,  441,   -1,  356,  357,  445,   -1,  447,   -1,   -1,
+   -1,   -1,   -1,  331,   -1,  405,   -1,   -1,   -1,   -1,
+   -1,   -1,  412,  413,   -1,  415,  416,   -1,  309,  419,
+  420,  421,  263,  264,   -1,   -1,   -1,  390,  356,  357,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  437,   -1,  439,
+  331,  441,  405,   -1,   -1,  445,   -1,  447,   -1,  412,
+  413,   -1,  415,  416,   -1,   -1,  419,  420,  421,  263,
+  264,   -1,  390,   -1,   -1,  356,  357,   -1,  309,   -1,
+   -1,   -1,  263,  264,  437,   -1,  439,  405,  441,   -1,
+   -1,   -1,   -1,   -1,  412,  413,   -1,  415,  416,   -1,
+  331,  419,  420,  421,   -1,   -1,   -1,   -1,   -1,  390,
+   -1,   -1,   -1,   -1,   -1,  309,   -1,   -1,   -1,  437,
+   -1,  439,   -1,  441,  405,  356,  357,   -1,  309,   -1,
+   -1,  412,  413,   -1,  415,  416,   -1,  331,  419,  420,
+  421,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  263,  264,
+  331,   -1,   -1,   -1,   -1,   -1,  437,   -1,  439,  390,
+  441,   -1,  356,  357,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  405,  356,  357,   -1,   -1,   -1,
+   -1,  412,  413,   -1,  415,  416,   -1,   -1,  419,  420,
+  421,  263,  264,   -1,  309,   -1,  390,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  437,   -1,  439,  390,
+  441,  405,   -1,   -1,   -1,   -1,  331,   -1,  412,  413,
+   -1,  415,  416,   -1,  405,  419,  420,  421,   -1,   -1,
+   -1,  412,  413,   -1,  415,  416,   -1,  309,  419,  420,
+  421,  356,  357,  437,   -1,  439,   -1,  441,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  437,   -1,  439,  331,
+  441,  263,  264,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  390,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  356,  357,   -1,   -1,   -1,   -1,
+  405,   -1,   -1,   -1,   -1,   -1,   -1,  412,  413,   -1,
+  415,  416,   -1,   -1,  419,  420,  421,  309,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  390,   -1,
+   -1,   -1,  437,   -1,  439,   -1,  441,   -1,   -1,  331,
+   -1,   -1,   -1,  405,   -1,   -1,   -1,   -1,   -1,   -1,
+  412,  413,   -1,  415,  416,   -1,   -1,  419,  420,  421,
+   -1,   -1,   -1,   -1,  356,  357,   -1,   -1,   -1,   -1,
+   -1,  257,   -1,   -1,   -1,  437,   -1,  439,   -1,  441,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  390,  285,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  297,  298,  405,   -1,   -1,   -1,   -1,   -1,   -1,
+  412,  413,  308,  415,  416,   -1,   -1,  419,  420,  421,
+   -1,  317,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  326,   -1,   -1,  257,  330,  437,   -1,  439,   -1,  441,
+   -1,   -1,   -1,  339,  340,   -1,   -1,   -1,  344,   -1,
+   -1,   -1,   -1,  349,  350,   -1,   -1,   -1,  354,   -1,
+   -1,  285,  358,  359,  360,   -1,   -1,  363,   -1,  365,
+  366,   -1,  368,  297,  298,   -1,   -1,   -1,   -1,   -1,
+  376,  377,   -1,   -1,  308,   -1,   -1,   -1,   -1,   -1,
+  386,   -1,   -1,  317,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  326,   -1,   -1,  257,  330,   -1,  404,   -1,
+   -1,   -1,   -1,   -1,   -1,  339,  340,   -1,   -1,   -1,
+  344,   -1,   -1,   -1,  420,  349,  350,   -1,   -1,   -1,
+  354,   -1,   -1,  285,  358,  359,  360,   -1,   -1,  363,
+   -1,  365,  366,   -1,  368,  297,  298,   -1,   -1,   -1,
+   -1,   -1,  376,  377,   -1,   -1,  308,   -1,   -1,   -1,
+   -1,   -1,  386,   -1,   -1,  317,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,  326,   -1,   -1,  257,  330,   -1,
+  404,   -1,   -1,   -1,   -1,   -1,   -1,  339,  340,   -1,
+   -1,   -1,  344,   -1,   -1,   -1,  420,  349,  350,   -1,
+   -1,   -1,  354,   -1,   -1,  285,  358,  359,  360,   -1,
+   -1,  363,   -1,  365,  366,   -1,  368,  297,  298,   -1,
+   -1,   -1,   -1,   -1,  376,  377,   -1,   -1,  308,   -1,
+   -1,   -1,   -1,   -1,  386,   -1,   -1,  317,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,  326,   -1,   -1,  257,
+  330,   -1,  404,   -1,   -1,   -1,   -1,   -1,   -1,  339,
+  340,   -1,   -1,   -1,  344,   -1,   -1,   -1,  420,  349,
+  350,   -1,   -1,   -1,   -1,   -1,   -1,  285,  358,  359,
+  360,   -1,   -1,  363,   -1,  365,  366,   -1,  368,  297,
+  298,   -1,   -1,   -1,   -1,   -1,  376,  377,   -1,   -1,
+  308,   -1,   -1,   -1,   -1,   -1,  386,   -1,   -1,  317,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  326,   -1,
+   -1,  257,  330,   -1,  404,   -1,   -1,   -1,   -1,   -1,
+   -1,  339,  340,   -1,   -1,   -1,  344,   -1,   -1,   -1,
+  420,  349,  350,   -1,   -1,   -1,   -1,   -1,   -1,  285,
+  358,  359,  360,   -1,   -1,  363,   -1,  365,  366,   -1,
+  368,  297,  298,   -1,   -1,   -1,   -1,   -1,  376,  377,
+   -1,   -1,  308,   -1,   -1,   -1,   -1,   -1,  386,   -1,
+   -1,  317,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  326,   -1,   -1,  257,  330,   -1,  404,   -1,   -1,   -1,
+   -1,   -1,   -1,  339,  340,   -1,   -1,   -1,  344,   -1,
+   -1,   -1,  420,  349,  350,   -1,   -1,   -1,   -1,   -1,
+   -1,  285,  358,  359,  360,   -1,   -1,  363,   -1,  365,
+  366,   -1,  368,  297,  298,   -1,   -1,   -1,   -1,   -1,
+  376,  377,  306,   -1,  308,   -1,   -1,   -1,   -1,   -1,
+  386,   -1,   -1,  317,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,  257,  330,   -1,  404,   -1,
+   -1,   -1,   -1,   -1,   -1,  339,  340,   -1,   -1,   -1,
+  344,   -1,   -1,   -1,  420,  349,  350,   -1,   -1,   -1,
+   -1,   -1,   -1,  285,  358,  359,  360,   -1,   -1,  363,
+   -1,  365,  366,   -1,  368,  297,  298,   -1,   -1,   -1,
+   -1,   -1,  376,  377,   -1,   -1,  308,   -1,   -1,   -1,
+   -1,   -1,  386,   -1,   -1,  317,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  257,  330,   -1,
+  404,   -1,   -1,   -1,   -1,   -1,   -1,  339,  340,   -1,
+   -1,   -1,  344,   -1,   -1,   -1,  420,  349,  350,   -1,
+   -1,   -1,   -1,   -1,   -1,  285,  358,  359,  360,   -1,
+   -1,  363,   -1,  365,  366,   -1,  368,  297,  298,   -1,
+   -1,   -1,   -1,   -1,  376,  377,   -1,   -1,  308,   -1,
+   -1,   -1,   -1,   -1,  386,   -1,   -1,  317,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+  330,   -1,  404,   -1,   -1,   -1,   -1,   -1,   -1,  339,
+  340,   -1,   -1,   -1,  344,   -1,   -1,   -1,  420,  349,
+  350,   -1,   -1,   -1,   -1,   -1,   -1,  285,  358,  359,
+  360,   -1,   -1,  363,   -1,  365,  366,   -1,  368,  297,
+  298,   -1,   -1,   -1,   -1,   -1,  376,  377,  306,   -1,
+  308,   -1,   -1,   -1,   -1,   -1,  386,   -1,   -1,  317,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  297,   -1,
+   -1,   -1,  330,   -1,  404,   -1,   -1,  306,   -1,   -1,
+   -1,  339,  340,   -1,   -1,   -1,  344,   -1,  317,  318,
+  420,  349,  350,   -1,   -1,   -1,   -1,   -1,   -1,  328,
+  358,  359,  360,   -1,   -1,  363,   -1,  365,  366,   -1,
+  368,  340,   -1,   -1,   -1,   -1,   -1,   -1,  376,  377,
+  349,  350,   -1,   -1,   -1,   -1,   -1,   -1,  386,  358,
+  359,  360,   -1,  297,  363,  364,  365,  366,   -1,  368,
+   -1,   -1,  306,   -1,   -1,   -1,  404,  376,  377,   -1,
+   -1,   -1,   -1,  317,  318,   -1,   -1,   -1,  387,   -1,
+   -1,   -1,  420,  297,  328,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,  306,   -1,   -1,  404,  340,   -1,   -1,   -1,
+   -1,   -1,   -1,  317,  318,  349,  350,   -1,   -1,   -1,
+   -1,  420,   -1,   -1,  358,  359,  360,   -1,  297,  363,
+  364,  365,  366,   -1,  368,   -1,  340,  306,   -1,   -1,
+   -1,   -1,  376,  377,   -1,  349,  350,   -1,  317,  318,
+   -1,   -1,   -1,  387,  358,  359,  360,   -1,  297,  363,
+  364,  365,  366,   -1,  368,   -1,   -1,  306,   -1,   -1,
+  404,  340,  376,  377,   -1,   -1,   -1,   -1,  317,  318,
+  349,  350,   -1,  387,   -1,   -1,  420,   -1,   -1,  358,
+  359,  360,   -1,  297,  363,  364,  365,  366,   -1,  368,
+  404,  340,  306,   -1,   -1,   -1,   -1,  376,  377,   -1,
+  349,  350,   -1,  317,  318,   -1,  420,   -1,  387,  358,
+  359,  360,   -1,  297,  363,  364,  365,  366,   -1,  368,
+   -1,   -1,  306,   -1,   -1,  404,  340,  376,  377,   -1,
+   -1,   -1,   -1,  317,  318,  349,  350,   -1,  387,   -1,
+   -1,  420,   -1,   -1,  358,  359,  360,   -1,   -1,  363,
+  364,  365,  366,   -1,  368,  404,  340,   -1,   -1,   -1,
+   -1,   -1,  376,  377,   -1,  349,  350,   -1,   -1,   -1,
+   -1,  420,   -1,  387,  358,  359,  360,   -1,   -1,  363,
+  364,  365,  366,   -1,  368,   -1,  285,   -1,   -1,   -1,
+  404,   -1,  376,  377,   -1,   -1,   -1,   -1,  297,  298,
+   -1,   -1,   -1,  387,   -1,   -1,  420,  306,   -1,  308,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  317,   -1,
+  404,   -1,   -1,   -1,   -1,   -1,  285,   -1,   -1,   -1,
+   -1,  330,   -1,   -1,   -1,   -1,  420,   -1,  297,  298,
+  339,  340,   -1,   -1,   -1,  344,   -1,  306,   -1,  308,
+  349,  350,   -1,   -1,   -1,   -1,   -1,   -1,  317,  358,
+  359,  360,   -1,   -1,  363,   -1,  365,  366,   -1,  368,
+   -1,  330,   -1,   -1,   -1,   -1,   -1,  376,  377,   -1,
+  339,  340,   -1,   -1,   -1,  344,   -1,  386,   -1,   -1,
+  349,  350,   -1,   -1,   -1,   -1,   -1,   -1,  285,  358,
+  359,  360,   -1,   -1,  363,  404,  365,  366,   -1,  368,
+  297,  298,   -1,   -1,   -1,   -1,   -1,  376,  377,   -1,
+   -1,  308,   -1,   -1,   -1,   -1,   -1,  386,   -1,   -1,
+  317,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,  330,   -1,  404,   -1,   -1,   -1,   -1,
+   -1,   -1,  339,  340,   -1,   -1,   -1,  344,   -1,   -1,
+   -1,   -1,  349,  350,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,  358,  359,  360,   -1,   -1,  363,   -1,  365,  366,
+   -1,  368,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  376,
+  377,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,  386,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
+   -1,   -1,   -1,   -1,   -1,   -1,   -1,  404,
+  };
+
+#line 4902 "mb-parser.jay"
+
+
+Tokenizer lexer;
+
+public Tokenizer Lexer {
+       get {
+               return lexer;
+       }
+}                 
+
+public static Expression DecomposeQI (string name, Location loc)
+{
+       Expression o;
+
+       if (name.IndexOf ('.') == -1){
+               return new SimpleName (name, loc);
+       } else {
+               int pos = name.LastIndexOf (".");
+               string left = name.Substring (0, pos);
+               string right = name.Substring (pos + 1);
+
+               o = DecomposeQI (left, loc);
+
+               return new MemberAccess (o, right, loc);
+       }
+}
+
+Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
+{
+       Block implicit_block;
+       ArrayList inits = null;
+
+       //
+       // We use the `Used' property to check whether statements
+       // have been added to the current block.  If so, we need
+       // to create another block to contain the new declaration
+       // otherwise, as an optimization, we use the same block to
+       // add the declaration.
+       //
+       // FIXME: A further optimization is to check if the statements
+       // that were added were added as part of the initialization
+       // below.  In which case, no other statements have been executed
+       // and we might be able to reduce the number of blocks for
+       // situations like this:
+       //
+       // int j = 1;  int k = j + 1;
+       //
+       
+       VariableDeclaration.FixupTypes (variable_declarators);
+       // FIXME: Should VariableDeclaration.FixupArrayTypes be called here
+
+       if (current_block.Used)
+               implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
+       else
+               implicit_block = current_block;
+
+
+       foreach (VariableDeclaration decl in variable_declarators){
+               Expression type = decl.type;
+               if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
+                       if (decl.expression_or_array_initializer != null){
+                               if (inits == null)
+                                       inits = new ArrayList ();
+                               inits.Add (decl);
+                       }
+               }
+       }
+
+       if (inits == null)
+               return implicit_block;
+
+       foreach (VariableDeclaration decl in inits){
+               Assign assign;
+               Expression expr;
+               Expression type = decl.type;
+               
+               if ((decl.expression_or_array_initializer is Expression) || 
+                   (decl.expression_or_array_initializer is New)) {
+                       expr = (Expression) decl.expression_or_array_initializer;
+               } else {
+                       ArrayList init = (ArrayList) decl.expression_or_array_initializer;
+                       
+                       expr = new ArrayCreation (type, "", init, decl.Location);
+               }
+
+               LocalVariableReference var;
+               var = new LocalVariableReference (implicit_block, decl.identifier, loc);
+
+               assign = new Assign (var, expr, decl.Location);
+
+               implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
+       }
+       
+       return implicit_block;
+}
+
+Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
+{
+       Block implicit_block;
+       VariableDeclaration.FixupTypes (variable_declarators);
+
+       if (current_block.Used)
+               implicit_block = new Block (current_block, Block.Flags.Implicit);
+       else
+               implicit_block = current_block;
+
+       foreach (VariableDeclaration decl in variable_declarators){
+               Expression type = decl.type;
+               implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
+                                         current_local_parameters, decl.Location);
+       }
+       
+       return implicit_block;
+}
+
+
+
+struct VarName {
+                public object Name;
+                public object Type;
+               public object Rank;
+                                                                                
+                public VarName (object n, object t, object r)
+                {
+                        Name = n;
+                        Type = t;
+                       Rank = r;
+                }
+        }
+
+
+// <summary>
+//   A class used to pass around variable declarations and constants
+// </summary>
+public class VariableDeclaration {
+       public string identifier;
+       public object expression_or_array_initializer;
+       public Location Location;
+       public Attributes OptAttributes;
+       public string DocComment;
+       public Expression type;
+       public ArrayList dims;
+               
+       public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
+       {
+               this.identifier = id;
+               this.expression_or_array_initializer = eoai;
+               this.Location = l;
+               this.OptAttributes = opt_attrs;
+               this.type = t;
+               this.dims = null;
+       }       
+
+       public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
+       {
+       }
+       
+       public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
+       {
+       }       
+       
+       public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this 
+                                       (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
+       {
+       }       
+       
+       public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
+       {       
+               // FIXME : This is broken: only the first rank is parsed
+               return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
+       }
+       
+       public static void FixupTypes (ArrayList vars)
+       {
+               int varcount =  vars.Count;
+               VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
+                       
+               if (last_var.type == null)
+                       last_var.type = TypeManager.system_object_expr;
+                       
+               Expression cur_type = last_var.type;
+               int n = varcount - 1;
+               
+               while (n >= 0) {
+                       VariableDeclaration var = (VariableDeclaration) vars[n--];
+                       if (var.type == null)
+                               var.type = cur_type;
+                       else
+                               cur_type = var.type;
+               }
+       }
+       
+       public static bool IndexesSpecifiedInRank (ArrayList IndexList)
+       {
+               bool res = false;
+               
+               if (IndexList != null) {
+                       foreach (Expression e in IndexList)
+                               if (!(e is EmptyExpression)) {
+                                       res = true;
+                                       break;
+                               }       
+               }
+               return (res);
+       }       
+       
+       
+       public static bool IndexesSpecified (ArrayList ranks)
+       {
+               bool res = false;
+               
+               if (ranks != null) {
+                       foreach (ArrayList IndexList in ranks) {
+                               if (IndexesSpecifiedInRank (IndexList)) {
+                                       res = true;
+                                       break;
+                               }       
+                       }       
+               }
+               return (res);
+       }
+       
+       public static string StripDims (string varname, ref string d)
+       {
+               string res = varname;
+               string dres = "";
+               
+               if (varname.IndexOf("[") >= 0) {
+                       dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
+                       res = varname.Substring(0, varname.IndexOf("["));
+               }
+               d = dres;
+               return (res);
+       }       
+       
+       public static string StripDims (string varname)
+       {
+               string dres = "";
+               
+               return (StripDims(varname, ref dres));
+       }       
+       
+       public static string StripIndexesFromDims (string dims)
+       {
+               StringBuilder sb = new StringBuilder();
+
+               foreach (char c in dims) 
+                       if (c == ',' || c == ']' || c == '[')
+                               sb.Append (c);
+                               
+               return sb.ToString();                           
+       }
+       
+       public static string BuildRank (ArrayList rank)
+       {
+               bool allEmpty;
+               return BuildRank(rank, out allEmpty);
+       }
+            
+       public static string BuildRank (ArrayList rank, out bool allEmpty)
+       {
+               string res = "";
+
+               res += "[";
+               allEmpty = true;
+               bool first = true;
+               foreach (object e in rank) {
+                       if (!(e is EmptyExpression))
+                               allEmpty = false;
+                       if (!first)
+                               res += ",";
+                       first = false;
+               }
+                       
+               res += "]";
+               return res;
+       }
+               
+       public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
+       {
+               string res = "";
+
+               bool allEmpty = true;
+               foreach (ArrayList rank in rank_specifiers) {
+                       bool tmp;
+                       res = BuildRank (rank, out tmp) + res;
+                       if (!tmp)
+                               allEmpty = false;
+               }
+               if (!allEmpty && mustBeEmpty)
+                       Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");    
+
+               return res;
+       }       
+       
+       public static void VBFixIndexList (ref ArrayList IndexList)
+       {
+               if (IndexList != null) {
+                       for (int x = 0; x < IndexList.Count; x++) {
+                               Expression e = (Expression) IndexList[x];
+                               if (!(e is EmptyExpression)) {
+                                       IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
+                               }
+                       }
+               }
+       }               
+       
+//     public static bool IsArrayDecl (Parser t)
+//     {
+//             // return (varname.IndexOf("[") >= 0);
+//             return (t.current_rank_specifiers != null);
+//     }                       
+       
+       public static void VBFixIndexLists (ref ArrayList ranks)
+       {       
+               if (ranks != null) {
+                       for (int x = 0; x < ranks.Count; x++) {
+                               ArrayList IndexList = (ArrayList) ranks[x];
+                               VBFixIndexList (ref IndexList);
+                       }       
+               }       
+       }
+               
+       public static void FixupArrayTypes (ArrayList vars)
+       {
+               int varcount =  vars.Count;
+               string dims;
+               
+               foreach (VariableDeclaration var in vars) {
+                       if (var.identifier.EndsWith(",")) {
+                               dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","), 
+                                                               var.identifier.LastIndexOf(",")) + "]";
+                               var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
+                               var.type = new ComposedCast (var.type, (string) dims, var.Location);
+                       }
+               }
+       }                               
+}
+
+
+// public Property BuildSimpleProperty (Expression p_type, string name, 
+//                                     Field p_fld, int mod_flags,
+//                                     Attributes attrs, Location loc) 
+// {
+//     Property p;
+//     Block get_block, set_block;
+//     Accessor acc_set, acc_get;
+//     StatementExpression a_set;
+//     Statement a_get;
+//     Parameter [] args;
+       
+//     // Build SET Block
+//     Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);    
+//     args  = new Parameter [1];
+//     args [0] = implicit_value_parameter;
+               
+//     Parameters set_params = new Parameters (args, null, loc);
+//     a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc), 
+//                         (Expression) new SimpleName("value", loc), loc), loc);
+                           
+//     set_block = new Block (current_block, set_params, loc, Location.Null);
+//     set_block.AddStatement ((Statement) a_set);                                         
+//     acc_set = new Accessor (set_block, attrs);
+       
+//     // Build GET Block
+//     a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
+//     get_block = new Block (current_block, null, loc, Location.Null);
+//     get_block.AddStatement ((Statement) a_get);                                         
+//     acc_get = new Accessor (get_block, attrs);
+               
+//     p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
+       
+//     return (p);
+// }
+       
+void start_block () 
+{
+         if (current_block == null){
+                 current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, 
+                                            current_local_parameters, lexer.Location);
+                 top_current_block = current_block;
+         } else {
+                 current_block = new Block (current_block, current_local_parameters,
+                                                lexer.Location, Location.Null);
+         }
+} 
+
+
+Block end_block ()
+{ 
+       Block res;
+
+       while (current_block.Implicit)
+               current_block = current_block.Parent;
+       res = current_block;
+       current_block.SetEndLocation (lexer.Location);
+       current_block = current_block.Parent;
+       if (current_block == null)
+               top_current_block = null;
+
+       return res;
+}
+
+// private void AddHandler (Expression evt_definition, Expression handler_exp)
+// {
+//     AddHandler (current_block, evt_definition, handler_exp);
+// }
+
+void CheckAttributeTarget (string a)
+{
+       switch (a) {
+
+       case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
+               return;
+               
+       default :
+               Location l = lexer.Location;
+               Report.Error (658, l, "`" + a + "' is an invalid attribute target");
+               break;
+       }
+}
+
+// private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
+// {
+//     Expression evt_target;
+//     Location loc = lexer.Location;
+       
+//     Statement addhnd = (Statement) new AddHandler (evt_id, 
+//                                                                                                     handles_exp, 
+//                                                                                                     loc);                                                                                                   
+                                                                                                       
+//     b.AddStatement (addhnd);
+// }
+
+// private void RaiseEvent (string evt_name, ArrayList args)
+// {
+//     Location loc = lexer.Location;
+       
+//     Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
+//     Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc)); 
+//     current_block.AddStatement (s); 
+// }
+
+// private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
+// {
+//     Expression evt_target;
+//     Location loc = lexer.Location;
+       
+//     Statement rmhnd = (Statement) new RemoveHandler (evt_definition, 
+//                                                                                                     handler_exp, 
+//                                                                                                     loc);
+//     b.AddStatement (rmhnd);
+// }
+
+// <summary>
+//  This method is used to get at the complete string representation of
+//  a fully-qualified type name, hiding inside a MemberAccess ;-)
+//  This is necessary because local_variable_type admits primary_expression
+//  as the type of the variable. So we do some extra checking
+// </summary>
+string GetQualifiedIdentifier (Expression expr)
+{
+       if (expr is SimpleName)
+               return ((SimpleName)expr).Name;
+       else if (expr is MemberAccess)
+               return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
+       else 
+               throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
+       
+}
+
+// private void RemoveHandler (Expression evt_definition, Expression handler_exp)
+// {
+//     RemoveHandler (current_block, evt_definition, handler_exp);
+// }
+
+// FIXME: This needs to be fixed for This and Base access because the way the name of the
+// mbas' constructor is changed from "New" to current_container.Basename
+
+private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
+{
+       ConstructorInitializer ci = null;
+       
+       if (s.Count > 0) {
+               if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
+                       Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
+                       
+                       if (i.expr is BaseAccess) {
+                               BaseAccess ba = (BaseAccess) i.expr;
+                               if (ba.member == "New" || ba.member == ".ctor") {
+                                       ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
+                                       s.RemoveAt(0);
+                               }
+                       }
+                       if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
+                               ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location); 
+                               s.RemoveAt(0);
+                       }
+               }
+       }
+       return ci;
+}
+
+void Error_ExpectingTypeName (Location l, Expression expr)
+{
+       if (expr is Invocation){
+               Report.Error (1002, l, "; expected");
+       } else {
+               Report.Error (-1, l, "Invalid Type definition");
+       }
+}
+
+static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
+       return true;
+}
+
+private void ReportError9998()
+{
+       Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
+}
+
+public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
+{
+       current_namespace = new NamespaceEntry (null, file, null, Location.Null);
+       this.name = file.Name;
+       this.file = file;
+       current_container = RootContext.Tree.Types;
+       current_container.NamespaceEntry = current_namespace;
+       oob_stack = new Stack ();
+       switch_stack = new Stack ();
+
+       lexer = new Tokenizer (reader, file, defines);
+
+       ifElseStateMachine = new IfElseStateMachine();
+       tokenizerController = new TokenizerController(lexer);
+}
+
+public void parse ()
+{
+       try {
+               if (yacc_verbose_flag > 1)
+                       yyparse (lexer, new yydebug.yyDebugSimple ());
+               else
+                       yyparse (lexer);
+               Tokenizer tokenizer = lexer as Tokenizer;
+               tokenizer.cleanup ();           
+       } catch (Exception e){
+               // 
+               // Removed for production use, use parser verbose to get the output.
+               //
+               // Console.WriteLine (e);
+               Report.Error (-25, lexer.Location, "Parsing error");
+               if (yacc_verbose_flag > 0)
+                       Console.WriteLine (e);
+       }
+}
+
+
+// protected override int parse ()
+// {
+//     RootContext.InitializeImports(ImportsList);
+//     current_namespace = new Namespace (null, RootContext.RootNamespace);
+//     current_container = RootContext.Tree.Types;
+//     current_container.Namespace = current_namespace;
+//     oob_stack = new Stack ();
+//     switch_stack = new Stack ();
+//     expr_stack = new Stack ();      
+//     tmp_blocks = new Stack(); 
+//     with_stack = new Stack();
+//     statement_stack = new Stack();  
+
+//     allow_global_attribs = true;
+//     expecting_global_attribs = false;
+//     expecting_local_attribs = false;
+//     local_attrib_section_added = false;
+
+//     UseExtendedSyntax = name.EndsWith(".mbs");
+//     OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
+//     OptionStrict = InitialOptionStrict || UseExtendedSyntax;
+//     OptionCompareBinary = InitialOptionCompareBinary;
+
+//     lexer = new Tokenizer (input, name, defines);
+       
+//     ifElseStateMachine = new IfElseStateMachine();
+//     tokenizerController = new TokenizerController(lexer);
+       
+//     StringBuilder value = new StringBuilder ();
+//     try {
+//             if (yacc_verbose_flag > 0)
+//                     yyparse (lexer, new yydebug.yyDebugSimple ());
+//             else {
+//                     yyparse (lexer);
+//                     cleanup();
+//             }
+//     } 
+//     catch(MBASException e) {
+//             Report.Error(e.code, e.loc, e.Message);
+//     }
+//     catch (Exception e) {
+//             if (Report.Stacktrace)
+//                     Console.WriteLine(e);
+//             Report.Error (29999, lexer.Location, "Parsing error");
+//     }
+
+//     RootContext.VerifyImports();
+
+//     return Report.Errors;
+// }
+
+// void cleanup()
+// {
+//     try {
+//             ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
+//     }
+//     catch(ApplicationException) {
+//             throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+//     }
+
+//     if(in_external_source) 
+//             Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
+
+//     if(in_marked_region > 0)
+//             Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
+// }
+
+void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
+{
+       try {
+               tokenizerController.PositionTokenizerCursor(tok, expr);
+       }
+       catch(ApplicationException) {
+               tok = IfElseStateMachine.Token.EOF;
+               try {
+                       ifElseStateMachine.HandleToken(tok);
+               }
+               catch(ApplicationException) {
+                       throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+               }
+       }
+}
+/* end end end */
+
+// <summary>
+//   Given the @class_name name, it creates a fully qualified name
+//   based on the containing declaration space
+// </summary>
+MemberName
+MakeName (MemberName class_name)
+{
+       string ns = current_namespace.FullName;
+
+       if (current_container.Name == ""){
+               if (ns != "")
+                       return new MemberName (new MemberName (ns), class_name);
+               else
+                       return class_name;
+       } else {
+               return new MemberName (current_container.MemberName, class_name);
+       }
+}
+
+}
+#line default
+namespace yydebug {
+        using System;
+        internal interface yyDebug {
+                void push (int state, Object value);
+                void lex (int state, int token, string name, Object value);
+                void shift (int from, int to, int errorFlag);
+                void pop (int state);
+                void discard (int state, int token, string name, Object value);
+                void reduce (int from, int to, int rule, string text, int len);
+                void shift (int from, int to);
+                void accept (Object value);
+                void error (string message);
+                void reject ();
+        }
+        
+        class yyDebugSimple : yyDebug {
+                void println (string s){
+                        Console.Error.WriteLine (s);
+                }
+                
+                public void push (int state, Object value) {
+                        println ("push\tstate "+state+"\tvalue "+value);
+                }
+                
+                public void lex (int state, int token, string name, Object value) {
+                        println("lex\tstate "+state+"\treading "+name+"\tvalue "+value);
+                }
+                
+                public void shift (int from, int to, int errorFlag) {
+                        switch (errorFlag) {
+                        default:                               // normally
+                                println("shift\tfrom state "+from+" to "+to);
+                                break;
+                        case 0: case 1: case 2:                // in error recovery
+                                println("shift\tfrom state "+from+" to "+to
+                                            +"\t"+errorFlag+" left to recover");
+                                break;
+                        case 3:                                // normally
+                                println("shift\tfrom state "+from+" to "+to+"\ton error");
+                                break;
+                        }
+                }
+                
+                public void pop (int state) {
+                        println("pop\tstate "+state+"\ton error");
+                }
+                
+                public void discard (int state, int token, string name, Object value) {
+                        println("discard\tstate "+state+"\ttoken "+name+"\tvalue "+value);
+                }
+                
+                public void reduce (int from, int to, int rule, string text, int len) {
+                        println("reduce\tstate "+from+"\tuncover "+to
+                                    +"\trule ("+rule+") "+text);
+                }
+                
+                public void shift (int from, int to) {
+                        println("goto\tfrom state "+from+" to "+to);
+                }
+                
+                public void accept (Object value) {
+                        println("accept\tvalue "+value);
+                }
+                
+                public void error (string message) {
+                        println("error\t"+message);
+                }
+                
+                public void reject () {
+                        println("reject");
+                }
+                
+        }
+}
+// %token constants
+ class Token {
+  public const int EOF = 257;
+  public const int NONE = 258;
+  public const int ERROR = 259;
+  public const int ADDHANDLER = 260;
+  public const int ADDRESSOF = 261;
+  public const int ALIAS = 262;
+  public const int AND = 263;
+  public const int ANDALSO = 264;
+  public const int ANSI = 265;
+  public const int AS = 266;
+  public const int ASSEMBLY = 267;
+  public const int AUTO = 268;
+  public const int BINARY = 269;
+  public const int BOOLEAN = 270;
+  public const int BYREF = 271;
+  public const int BYTE = 272;
+  public const int BYVAL = 273;
+  public const int CALL = 274;
+  public const int CASE = 275;
+  public const int CATCH = 276;
+  public const int CBOOL = 277;
+  public const int CBYTE = 278;
+  public const int CCHAR = 279;
+  public const int CDATE = 280;
+  public const int CDEC = 281;
+  public const int CDBL = 282;
+  public const int CHAR = 283;
+  public const int CINT = 284;
+  public const int CLASS = 285;
+  public const int CLNG = 286;
+  public const int COBJ = 287;
+  public const int COMPARE = 288;
+  public const int CONST = 289;
+  public const int CSHORT = 290;
+  public const int CSNG = 291;
+  public const int CSTR = 292;
+  public const int CTYPE = 293;
+  public const int DATE = 294;
+  public const int DECIMAL = 295;
+  public const int DECLARE = 296;
+  public const int DEFAULT = 297;
+  public const int DELEGATE = 298;
+  public const int DIM = 299;
+  public const int DIRECTCAST = 300;
+  public const int DO = 301;
+  public const int DOUBLE = 302;
+  public const int EACH = 303;
+  public const int ELSE = 304;
+  public const int ELSEIF = 305;
+  public const int END = 306;
+  public const int ENDIF = 307;
+  public const int ENUM = 308;
+  public const int EOL = 309;
+  public const int ERASE = 310;
+  public const int EVENT = 311;
+  public const int EXIT = 312;
+  public const int EXPLICIT = 313;
+  public const int FALSE = 314;
+  public const int FINALLY = 315;
+  public const int FOR = 316;
+  public const int FRIEND = 317;
+  public const int FUNCTION = 318;
+  public const int GET = 319;
+  public const int GETTYPE = 320;
+  public const int GOSUB = 321;
+  public const int GOTO = 322;
+  public const int HANDLES = 323;
+  public const int IF = 324;
+  public const int IMPLEMENTS = 325;
+  public const int IMPORTS = 326;
+  public const int IN = 327;
+  public const int INHERITS = 328;
+  public const int INTEGER = 329;
+  public const int INTERFACE = 330;
+  public const int IS = 331;
+  public const int LET = 332;
+  public const int LIB = 333;
+  public const int LIKE = 334;
+  public const int LONG = 335;
+  public const int LOOP = 336;
+  public const int ME = 337;
+  public const int MOD = 338;
+  public const int MODULE = 339;
+  public const int MUSTINHERIT = 340;
+  public const int MUSTOVERRIDE = 341;
+  public const int MYBASE = 342;
+  public const int MYCLASS = 343;
+  public const int NAMESPACE = 344;
+  public const int NEW = 345;
+  public const int NEXT = 346;
+  public const int NOT = 347;
+  public const int NOTHING = 348;
+  public const int NOTINHERITABLE = 349;
+  public const int NOTOVERRIDABLE = 350;
+  public const int OBJECT = 351;
+  public const int OFF = 352;
+  public const int ON = 353;
+  public const int OPTION = 354;
+  public const int OPTIONAL = 355;
+  public const int OR = 356;
+  public const int ORELSE = 357;
+  public const int OVERLOADS = 358;
+  public const int OVERRIDABLE = 359;
+  public const int OVERRIDES = 360;
+  public const int PARAM_ARRAY = 361;
+  public const int PRESERVE = 362;
+  public const int PRIVATE = 363;
+  public const int PROPERTY = 364;
+  public const int PROTECTED = 365;
+  public const int PUBLIC = 366;
+  public const int RAISEEVENT = 367;
+  public const int READONLY = 368;
+  public const int REDIM = 369;
+  public const int REM = 370;
+  public const int REMOVEHANDLER = 371;
+  public const int RESUME = 372;
+  public const int RETURN = 373;
+  public const int SELECT = 374;
+  public const int SET = 375;
+  public const int SHADOWS = 376;
+  public const int SHARED = 377;
+  public const int SHORT = 378;
+  public const int SINGLE = 379;
+  public const int SIZEOF = 380;
+  public const int STATIC = 381;
+  public const int STEP = 382;
+  public const int STOP = 383;
+  public const int STRICT = 384;
+  public const int STRING = 385;
+  public const int STRUCTURE = 386;
+  public const int SUB = 387;
+  public const int SYNCLOCK = 388;
+  public const int TEXT = 389;
+  public const int THEN = 390;
+  public const int THROW = 391;
+  public const int TO = 392;
+  public const int TRUE = 393;
+  public const int TRY = 394;
+  public const int TYPEOF = 395;
+  public const int UNICODE = 396;
+  public const int UNTIL = 397;
+  public const int VARIANT = 398;
+  public const int WEND = 399;
+  public const int WHEN = 400;
+  public const int WHILE = 401;
+  public const int WITH = 402;
+  public const int WITHEVENTS = 403;
+  public const int WRITEONLY = 404;
+  public const int XOR = 405;
+  public const int YIELD = 406;
+  public const int HASH = 407;
+  public const int OPEN_BRACKET = 408;
+  public const int CLOSE_BRACKET = 409;
+  public const int OPEN_PARENS = 410;
+  public const int OPEN_BRACE = 411;
+  public const int CLOSE_BRACE = 412;
+  public const int CLOSE_PARENS = 413;
+  public const int DOT = 414;
+  public const int COMMA = 415;
+  public const int COLON = 416;
+  public const int PLUS = 417;
+  public const int MINUS = 418;
+  public const int ASSIGN = 419;
+  public const int OP_LT = 420;
+  public const int OP_GT = 421;
+  public const int STAR = 422;
+  public const int DIV = 423;
+  public const int OP_EXP = 424;
+  public const int INTERR = 425;
+  public const int OP_IDIV = 426;
+  public const int OP_CONCAT = 427;
+  public const int EXCLAMATION = 428;
+  public const int PERCENT = 429;
+  public const int LONGTYPECHAR = 430;
+  public const int AT_SIGN = 431;
+  public const int SINGLETYPECHAR = 432;
+  public const int NUMBER_SIGN = 433;
+  public const int DOLAR_SIGN = 434;
+  public const int ATTR_ASSIGN = 435;
+  public const int OP_LE = 437;
+  public const int OP_GE = 439;
+  public const int OP_NE = 441;
+  public const int OP_XOR = 443;
+  public const int xor = 444;
+  public const int OP_SHIFT_LEFT = 445;
+  public const int OP_SHIFT_RIGHT = 447;
+  public const int LITERAL_INTEGER = 449;
+  public const int LITERAL_SINGLE = 451;
+  public const int LITERAL_DOUBLE = 453;
+  public const int LITERAL_DECIMAL = 455;
+  public const int LITERAL_CHARACTER = 457;
+  public const int LITERAL_STRING = 459;
+  public const int LITERAL_DATE = 461;
+  public const int IDENTIFIER = 463;
+  public const int LOWPREC = 464;
+  public const int OP_OR = 465;
+  public const int OP_AND = 466;
+  public const int BITWISE_OR = 467;
+  public const int BITWISE_AND = 468;
+  public const int BITWISE_NOT = 469;
+  public const int CARRET = 470;
+  public const int UMINUS = 471;
+  public const int OP_INC = 472;
+  public const int OP_DEC = 473;
+  public const int HIGHPREC = 474;
+  public const int label_name = 475;
+  public const int yyErrorCode = 256;
+ }
+ namespace yyParser {
+  using System;
+  /** thrown for irrecoverable syntax errors and stack overflow.
+    */
+  internal class yyException : System.Exception {
+    public yyException (string message) : base (message) {
+    }
+  }
+
+  /** must be implemented by a scanner object to supply input to the parser.
+    */
+  internal interface yyInput {
+    /** move on to next token.
+        @return false if positioned beyond tokens.
+        @throws IOException on input error.
+      */
+    bool advance (); // throws java.io.IOException;
+    /** classifies current token.
+        Should not be called if advance() returned false.
+        @return current %token or single character.
+      */
+    int token ();
+    /** associated with current token.
+        Should not be called if advance() returned false.
+        @return value for token().
+      */
+    Object value ();
+  }
+ }
+} // close outermost namespace, that MUST HAVE BEEN opened in the prolog
diff --git a/mcs/bmcs/mb-parser.jay b/mcs/bmcs/mb-parser.jay
new file mode 100644 (file)
index 0000000..97172ad
--- /dev/null
@@ -0,0 +1,5563 @@
+%{
+//
+// Mono.MonoBASIC.Parser.cs (from .jay): The Parser for the MonoBASIC compiler
+//
+// Authors: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+//         Anirban Bhattacharjee (banirban@novell.com)
+//          Jambunathan K (kjambunathan@novell.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// Copyright (C) 2001, 2002, 2003, 2004 A Rafael D Teixeira
+// Copyright (C) 2003, 2004 Novell
+//
+//
+
+namespace Mono.CSharp
+{
+       using System.Text;
+       using System;
+       using System.Reflection;
+       using System.Collections;
+       using Mono.CSharp;
+
+       /// <summary>
+       ///    The MonoBASIC Parser
+       /// </summary>
+//     [DefaultParser]
+//     public class Parser : GenericParser
+//     {
+       
+
+//             /// <summary>
+//             ///   Current block is used to add statements as we find
+//             ///   them.  
+//             /// </summary>
+//             Block      current_block;
+               
+//             /// <summary>
+//             ///   Tmp block is used to store block endings in if/select's
+//             /// </summary>
+//             Block      tmp_block;           
+
+//             /// <summary>
+//             ///   Tmp block is used to store tmp copies of expressions
+//             /// </summary>
+//             Expression      tmp_expr;       
+               
+//             /// <summary>
+//             ///   Tmp catch is used to store catch clauses in try..catch..finally
+//             /// </summary>
+//             ArrayList      tmp_catch_clauses;                       
+               
+//             /// <summary>
+//             ///   Current interface is used by the various declaration
+//             ///   productions in the interface declaration to "add"
+//             ///   the interfaces as we find them.
+//             /// </summary>
+//             Interface  current_interface;
+
+//             /// <summary>
+//             ///   This is used by the unary_expression code to resolve
+//             ///   a name against a parameter.  
+//             /// </summary>
+//             Parameters current_local_parameters;
+               
+//             /// <summary>
+//             ///   This are used when parsing parameters in property
+//             ///   declarations.
+//             /// </summary>          
+//             Parameters set_parameters;
+//             Parameters get_parameters;
+               
+//             /// <summary>
+//             ///   This is used by the sub_header parser to store modifiers
+//             ///   to be passed to sub/constructor  
+//             /// </summary>
+//             int current_modifiers;          
+                       
+//             /// <summary>
+//             ///   This is used by the sub_header parser to store attributes
+//             ///   to be passed to sub/constructor  
+//             /// </summary>
+//             Attributes current_attributes;                          
+
+//             /// <summary>
+//             ///   Using during property parsing to describe the implicit
+//             ///   value parameter that is passed to the "set" accessor
+//             ///   method
+//             /// </summary>
+//             string get_implicit_value_parameter_name;
+               
+//             // <summary>
+//             //   Using during property parsing to describe the implicit
+//             //   value parameter that is passed to the "set" and "get"accesor
+//             //   methods (properties and indexers).
+//             // </summary>
+//             Expression get_implicit_value_parameter_type;
+               
+//             /// <summary>
+//             ///   Using during property parsing to describe the implicit
+//             ///   value parameter that is passed to the "set" accessor
+//             ///   method
+//             /// </summary>
+//             string set_implicit_value_parameter_name;
+               
+//             // <summary>
+//             //   Using during property parsing to describe the implicit
+//             //   value parameter that is passed to the "set" and "get"accesor
+//             //   methods (properties and indexers).
+//             // </summary>
+//             Expression set_implicit_value_parameter_type;           
+               
+//             Location member_location;
+               
+//             // An out-of-band stack.
+//             //
+//             Stack oob_stack;
+               
+//             ArrayList current_rank_specifiers;
+
+//             DoOptions do_type;
+//             //
+//             // Switch stack.
+//             //
+//             Stack switch_stack;
+               
+//             // Expression stack for nested ifs
+//             Stack expr_stack; 
+               
+//             Stack tmp_blocks;
+//             Stack statement_stack;
+
+//             // A stack for With expressions.
+//             //
+//             Stack with_stack;
+       
+               
+//             static public bool InitialOptionExplicit = false;
+//             static public bool InitialOptionStrict = false;
+//             static public bool InitialOptionCompareBinary = true;
+//             static public ArrayList ImportsList = null;
+
+//             bool OptionExplicit;
+//             bool OptionStrict;
+//             bool OptionCompareBinary;
+
+//             static public bool UseExtendedSyntax; // for ".mbs" files
+
+//             bool implicit_modifiers;
+               
+//             public override string[] extensions()
+//             {
+//                     string [] list = { ".vb", ".mbs" };
+//                     return list;
+//             }
+
+
+       /// <summary>
+       ///    The C# Parser
+       /// </summary>
+       public class CSharpParser {
+               NamespaceEntry  current_namespace;
+               TypeContainer   current_container;
+               TypeContainer   current_class;
+       
+               IIteratorContainer iterator_container;
+
+               /// <summary>
+               ///   Current block is used to add statements as we find
+               ///   them.  
+               /// </summary>
+               Block      current_block, top_current_block;
+
+               /// <summary>
+               ///   This is used by the unary_expression code to resolve
+               ///   a name against a parameter.  
+               /// </summary>
+               Parameters current_local_parameters;
+
+               /// <summary>
+               ///   Using during property parsing to describe the implicit
+               ///   value parameter that is passed to the "set" and "get"accesor
+               ///   methods (properties and indexers).
+               /// </summary>
+               Expression implicit_value_parameter_type;
+               Parameters indexer_parameters;
+
+               /// <summary>
+               ///   Used to determine if we are parsing the get/set pair
+               ///   of an indexer or a property
+               /// </summmary>
+               bool  parsing_indexer;
+
+               ///
+               /// An out-of-band stack.
+               ///
+               Stack oob_stack;
+
+               ///
+               /// Switch stack.
+               ///
+               Stack switch_stack;
+
+               static public int yacc_verbose_flag;
+
+               // Name of the file we are parsing
+               public string name;
+
+               ///
+               /// The current file.
+               ///
+               SourceFile file;
+               
+               ///   This is used by the sub_header parser to store modifiers
+               ///   to be passed to sub/constructor  
+               int current_modifiers;          
+                       
+               ///   This is used by the sub_header parser to store attributes
+               ///   to be passed to sub/constructor  
+               Attributes current_attributes;                          
+
+               ///   This is used by the attributes parser to syntactically
+               ///   validate the attribute rules  
+               bool allow_global_attribs = true;
+
+               bool expecting_global_attribs = false;
+               bool expecting_local_attribs = false;
+
+               bool local_attrib_section_added = false;
+
+               ///FIXME
+               ArrayList current_rank_specifiers;
+
+               /// <summary>
+               ///   Using during property parsing to describe the implicit
+               ///   value parameter that is passed to the "set" accessor
+               ///   method
+               /// </summary>
+               string get_implicit_value_parameter_name;
+               
+               // <summary>
+               //   Using during property parsing to describe the implicit
+               //   value parameter that is passed to the "set" and "get"accesor
+               //   methods (properties and indexers).
+               // </summary>
+               Expression get_implicit_value_parameter_type;
+               
+               /// <summary>
+               ///   Using during property parsing to describe the implicit
+               ///   value parameter that is passed to the "set" accessor
+               ///   method
+               /// </summary>
+               string set_implicit_value_parameter_name;
+               
+               // <summary>
+               //   Using during property parsing to describe the implicit
+               //   value parameter that is passed to the "set" and "get"accesor
+               //   methods (properties and indexers).
+               // </summary>
+               Expression set_implicit_value_parameter_type;           
+
+               /// <summary>
+               ///   This are used when parsing parameters in property
+               ///   declarations.
+               /// </summary>          
+               Parameters set_parameters;
+               Parameters get_parameters;
+
+//             static public ArrayList ImportsList = null;
+
+               bool implicit_modifiers;
+
+
+               /// <summary>
+               ///   This is used as a helper class for handling of
+               ///   pre-processor statements.
+               /// </summary>          
+
+               // FIXME: This class MBASException is actually a kludge 
+               // It can be done away with a more elegant replacement.
+
+               public class MBASException : ApplicationException
+               {
+                       public int code;
+                       public Location loc;
+
+                       public MBASException(int code, Location loc, string text) : base(text)
+                       {
+                               this.code = code;
+                               this.loc = loc;
+                       }
+               }
+
+
+
+               public class IfElseStateMachine {
+                       
+                       public enum State {
+                               START,
+                               IF_SEEN,
+                               ELSEIF_SEEN,
+                               ELSE_SEEN,
+                               ENDIF_SEEN,
+                               MAX
+                       }
+               
+                       public enum Token {
+                               START,
+                               IF,
+                               ELSEIF,
+                               ELSE,
+                               ENDIF,
+                               EOF,
+                               MAX
+                       }
+
+                       State state;
+                       Stack stateStack;
+
+                       public static Hashtable errStrings = new Hashtable();
+
+                       int err=0;
+                       static int[,] errTable = new int[(int)State.MAX, (int)Token.MAX];
+               
+                       static IfElseStateMachine()
+                       {
+                               // FIXME: Fix both the error nos and the error strings. 
+                               // Currently the error numbers and the error strings are 
+                               // just placeholders for getting the state-machine going.
+
+                               errStrings.Add(0, "");
+                               errStrings.Add(30012, "#If must end with a matching #End If");
+                               errStrings.Add(30013, "#ElseIf, #Else or #End If must be preceded by a matching #If");
+                               errStrings.Add(30014, "#ElseIf must be preceded by a matching #If or #ElseIf");
+                               errStrings.Add(30028, "#Else must be preceded by a matching #If or #ElseIf");
+                               errStrings.Add(32030, "#ElseIf cannot follow #Else as part of #If block");
+
+                               errTable[(int)State.START, (int)Token.IF] = 0;
+                               errTable[(int)State.START, (int)Token.ELSEIF] = 30014;
+                               errTable[(int)State.START, (int)Token.ELSE] = 30028;
+                               errTable[(int)State.START, (int)Token.ENDIF] = 30013;
+                               errTable[(int)State.START, (int)Token.EOF] = 0;
+
+                               errTable[(int)State.IF_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.ELSEIF] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.ELSE] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.ENDIF] = 0;
+                               errTable[(int)State.IF_SEEN, (int)Token.EOF] = 30012;
+
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSEIF] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.ELSE] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.ENDIF] = 0;
+                               errTable[(int)State.ELSEIF_SEEN, (int)Token.EOF] = 30012;
+
+                               errTable[(int)State.ELSE_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.ELSEIF] = 32030;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.ELSE] = 32030;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.ENDIF] = 0;
+                               errTable[(int)State.ELSE_SEEN, (int)Token.EOF] = 30012;
+
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.IF] = 0;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.ELSEIF] = 30014;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.ELSE] = 30028;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.ENDIF] = 30013;
+                               errTable[(int)State.ENDIF_SEEN, (int)Token.EOF] = 0;
+                       }
+
+                       public IfElseStateMachine()
+                       {
+                               state = State.START;
+
+                               stateStack = new Stack();
+                               stateStack.Push(state);
+                       }
+
+                       // The parameter here need not be qualified with IfElseStateMachine
+                       // But it hits a bug in mcs. So temporarily scoping it so that builds
+                       // are not broken.
+
+                       public void HandleToken(IfElseStateMachine.Token tok)
+                       {       
+                               err = (int) errTable[(int)state, (int)tok];
+
+                               if(err != 0)
+                                       throw new ApplicationException("Unexpected pre-processor directive #"+tok); 
+                               
+                               if(tok == Token.IF) {
+                                       stateStack.Push(state);
+                                       state = (State) tok;
+                               }
+                               else if(tok == Token.ENDIF) {
+                                       state = (State)stateStack.Pop();
+                               }
+                               else
+                                       state = (State)tok;
+                       }
+
+                       public int Error {
+                               get {
+                                       return err;
+                               }
+                       }
+
+                       public string ErrString {
+                               get {
+                                       return (string) errStrings[err];
+                               }
+                       }
+               }
+
+               
+               public class TokenizerController {
+                       
+                       struct State
+                       {
+                               public bool CanAcceptTokens;
+                               public bool CanSelectBlock;
+
+                       }
+
+                       State currentState;
+                       Stack stateStack;
+                       Tokenizer lexer;
+
+                       public TokenizerController(Tokenizer lexer)
+                       {
+                               this.lexer = lexer;
+                               stateStack = new Stack();
+
+                               currentState.CanAcceptTokens = true;
+                               currentState.CanSelectBlock = true;
+
+                               stateStack.Push(currentState);
+                       }
+
+                       State parentState {
+                               get {
+                                       return (State)stateStack.Peek();
+                               }
+                       }
+
+                       public bool IsAcceptingTokens {
+                               get {
+                                       return currentState.CanAcceptTokens;
+                               }
+                       }
+
+                       public void PositionCursorAtNextPreProcessorDirective()
+                       {
+                               lexer.PositionCursorAtNextPreProcessorDirective();
+                       }
+
+                       public void PositionTokenizerCursor(IfElseStateMachine.Token tok, BoolLiteral expr)
+                       {
+                               if(tok == IfElseStateMachine.Token.ENDIF) {
+                                       currentState = (State)stateStack.Pop();
+
+                                       if(currentState.CanAcceptTokens)
+                                               return;
+                                       else {
+                                               PositionCursorAtNextPreProcessorDirective();
+                                               return;
+                                       }
+                               }
+                               
+                               if(tok == IfElseStateMachine.Token.IF) {
+                                       stateStack.Push(currentState);
+                                       
+                                       currentState.CanAcceptTokens = parentState.CanAcceptTokens;
+                                       currentState.CanSelectBlock = true;
+                               }
+                       
+                               if(parentState.CanAcceptTokens && 
+                                  currentState.CanSelectBlock && (bool)(expr.GetValue()) ) {
+                                   
+                                       currentState.CanAcceptTokens = true;
+                                       currentState.CanSelectBlock = false; 
+                                       return;
+                               }
+                               else {
+                                       currentState.CanAcceptTokens = false;
+                                       PositionCursorAtNextPreProcessorDirective();
+                                       return;
+                               }
+                       }
+               }
+
+               bool in_external_source = false;
+               int in_marked_region = 0;
+
+               TokenizerController tokenizerController;
+               IfElseStateMachine ifElseStateMachine;
+
+
+
+%}
+
+%token EOF
+%token NONE   /* This token is never returned by our lexer */
+%token ERROR  // This is used not by the parser, but by the tokenizer.
+             // do not remove.
+
+/*
+ *These are the MonoBASIC keywords
+ */
+%token ADDHANDLER
+%token ADDRESSOF
+%token ALIAS
+%token AND
+%token ANDALSO
+%token ANSI
+%token AS
+%token ASSEMBLY
+%token AUTO
+%token BINARY
+%token BOOLEAN 
+%token BYREF
+%token BYTE
+%token BYVAL   
+%token CALL
+%token CASE    
+%token CATCH   
+%token CBOOL
+%token CBYTE
+%token CCHAR   
+%token CDATE
+%token CDEC
+%token CDBL
+%token CHAR    
+%token CINT
+%token CLASS
+%token CLNG
+%token COBJ
+%token COMPARE 
+%token CONST   
+%token CSHORT  
+%token CSNG
+%token CSTR
+%token CTYPE
+%token DATE
+%token DECIMAL 
+%token DECLARE
+%token DEFAULT 
+%token DELEGATE        
+%token DIM
+%token DIRECTCAST
+%token DO      
+%token DOUBLE  
+%token EACH    
+%token ELSE
+%token ELSEIF
+%token END
+%token ENDIF
+%token ENUM    
+%token EOL
+%token ERASE
+%token ERROR
+%token EVENT
+%token EXIT    
+%token EXPLICIT        
+%token FALSE   
+%token FINALLY 
+%token FOR     
+%token FRIEND
+%token FUNCTION
+%token GET
+%token GETTYPE
+%token GOSUB
+%token GOTO    
+%token HANDLES
+%token IF      
+%token IMPLEMENTS
+%token IMPORTS 
+%token IN      
+%token INHERITS
+%token INTEGER 
+%token INTERFACE
+%token IS
+%token LET
+%token LIB     
+%token LIKE    
+%token LONG    
+%token LOOP
+%token ME
+%token MOD
+%token MODULE
+%token MUSTINHERIT     
+%token MUSTOVERRIDE
+%token MYBASE
+%token MYCLASS
+%token NAMESPACE
+%token NEW
+%token NEXT    
+%token NOT
+%token NOTHING
+%token NOTINHERITABLE
+%token NOTOVERRIDABLE
+%token OBJECT  
+%token OFF
+%token ON
+%token OPTION  
+%token OPTIONAL        
+%token OR
+%token ORELSE
+%token OVERLOADS
+%token OVERRIDABLE     
+%token OVERRIDES       
+%token PARAM_ARRAY
+%token PRESERVE
+%token PRIVATE 
+%token PROPERTY
+%token PROTECTED
+%token PUBLIC
+%token RAISEEVENT
+%token READONLY        
+%token REDIM
+%token REM
+%token REMOVEHANDLER
+%token RESUME  
+%token RETURN
+%token SELECT
+%token SET
+%token SHADOWS
+%token SHARED
+%token SHORT   
+%token SINGLE
+%token SIZEOF  
+%token STATIC  
+%token STEP
+%token STOP
+%token STRICT  
+%token STRING
+%token STRUCTURE
+%token SUB
+%token SYNCLOCK
+%token TEXT
+%token THEN
+%token THROW
+%token TO
+%token TRUE    
+%token TRY     
+%token TYPEOF  
+%token UNICODE
+%token UNTIL
+%token VARIANT 
+%token WEND
+%token WHEN    
+%token WHILE   
+%token WITH
+%token WITHEVENTS
+%token WRITEONLY
+%token XOR
+%token YIELD // MonoBASIC extension
+
+%token HASH
+
+/* MonoBASIC single character operators/punctuation. */
+
+%token OPEN_BRACKET  "["
+%token CLOSE_BRACKET "]"
+%token OPEN_PARENS   "("
+%token OPEN_BRACE    "{"
+%token CLOSE_BRACE   "}"
+%token CLOSE_PARENS  ")"
+%token DOT           "."
+%token COMMA         ","
+%token COLON         ":"
+
+%token PLUS           "+"
+%token MINUS          "-"
+%token ASSIGN         "="
+%token OP_LT          "<"
+%token OP_GT          ">"
+%token STAR           "*"
+%token DIV            "/"
+%token OP_EXP         "^"
+%token INTERR         "?"
+%token OP_IDIV        "\\" //FIXME: This should be "\"
+%token OP_CONCAT      "&"
+%token EXCLAMATION    "!"
+
+%token PERCENT        "%"
+%token LONGTYPECHAR   "&"
+%token AT_SIGN           "@"
+%token SINGLETYPECHAR "!"
+%token NUMBER_SIGN    "#"
+%token DOLAR_SIGN     "$"
+
+%token ATTR_ASSIGN       ":="
+
+/* MonoBASIC multi-character operators. */
+%token OP_LE                  "<="
+%token OP_GE                  ">="
+%token OP_NE                  "<>"
+%token OP_XOR                 "xor"
+//%token OP_MODULUS             //"mod"
+
+/* VB.NET 2003 new bit-shift operators */
+%token OP_SHIFT_LEFT             "<<"
+%token OP_SHIFT_RIGHT         ">>"
+
+/* Numbers */
+%token LITERAL_INTEGER           "int literal"
+%token LITERAL_SINGLE            "float literal"
+%token LITERAL_DOUBLE            "double literal"
+%token LITERAL_DECIMAL           "decimal literal"
+%token LITERAL_CHARACTER         "character literal"
+%token LITERAL_STRING            "string literal"
+%token LITERAL_DATE              "datetime literal"
+
+%token IDENTIFIER
+
+/* Add precedence rules to solve dangling else s/r conflict */
+%nonassoc LOWPREC
+%nonassoc IF
+%nonassoc ELSE
+%right ASSIGN
+%left OP_OR
+%left OP_AND
+%left BITWISE_OR
+%left BITWISE_AND
+%left OP_SHIFT_LEFT OP_SHIFT_RIGHT
+%left PLUS MINUS
+%left STAR DIV PERCENT
+%right BITWISE_NOT CARRET UMINUS
+%nonassoc OP_INC OP_DEC
+%left OPEN_PARENS
+%left OPEN_BRACKET OPEN_BRACE
+%left DOT
+%right NOT
+%nonassoc HIGHPREC
+
+%start compilation_unit
+%%
+
+end_of_stmt
+       : logical_end_of_line
+       | COLON
+       ;       
+
+logical_end_of_line
+       : EOL
+       | logical_end_of_line pp_directive 
+       ;
+
+compilation_unit
+       : logical_end_of_line
+         opt_option_directives
+         opt_imports_directives 
+         declarations 
+         EOF
+         {
+               $$=$4;
+         }
+       |logical_end_of_line
+         opt_option_directives
+         opt_imports_directives 
+         opt_attributes
+         EOF
+         {
+               /* ????? */ ;
+         }
+       ;
+         
+opt_option_directives
+       : /* empty */
+       | option_directives
+       ;
+       
+option_directives
+       : option_directive
+       | option_directives option_directive
+       ;
+       
+option_directive
+       : option_explicit_directive
+       | option_strict_directive
+       | option_compare_directive
+       ;
+       
+on_off
+       : /* empty */
+         {
+                 $$ = (object)true;
+         }
+       | ON
+         {
+                 $$ = (object)true;
+         }
+       | OFF
+         {
+                 $$ = (object)false;
+         }
+       ;
+         
+text_or_binary
+       : BINARY
+         {
+                 $$ = (object)true;
+         }
+       | TEXT
+         {
+                 $$ = (object)false;
+         }
+       ;
+         
+option_explicit_directive
+       : OPTION EXPLICIT on_off logical_end_of_line
+         {
+//             if (!UseExtendedSyntax)
+//                     OptionExplicit = (bool)$3;
+//             else
+//                     Report.Warning (
+//                             9999, lexer.Location, 
+//                             "In MonoBASIC extended syntax explicit declaration is always required. So OPTION EXPLICIT is deprecated");
+         }
+       ;
+         
+                       
+option_strict_directive
+       : OPTION STRICT on_off logical_end_of_line
+         {
+//             if (!UseExtendedSyntax)
+//                     OptionStrict = (bool)$3;
+//             else
+//                     Report.Warning (
+//                             9999, lexer.Location, 
+//                             "In MonoBASIC extended syntax strict assignability is always required. So OPTION STRICT is deprecated");
+         }
+       ;
+         
+option_compare_directive
+       : OPTION COMPARE text_or_binary logical_end_of_line
+         {
+//             OptionCompareBinary = (bool)$3;
+         }
+       ;
+
+opt_declarations
+       : /* empty */
+       | declarations
+       ;               
+
+declarations
+       : declaration
+       | declarations declaration
+       ;
+       
+declaration
+       : declaration_qualifiers
+         {
+//             FIXME: Need to check declaration qualifiers for multi-file compilation
+//             FIXME: Qualifiers cannot be applied to namespaces
+               allow_global_attribs = false;
+         }
+         namespace_declaration
+         {
+               current_namespace.DeclarationFound = true;
+         }
+       | declaration_qualifiers
+         {
+                 // FIXME: Need to check declaration qualifiers for multi-file compilation
+                 allow_global_attribs = false;
+         }
+         type_spec_declaration
+         {
+               string name = "";
+               int mod_flags;
+
+               if ($3 is Class){
+                       Class c = (Class) $3;
+                       mod_flags = c.ModFlags;
+                       name = c.Name;
+               } else if ($3 is Struct){
+                       Struct s = (Struct) $3;
+                       mod_flags = s.ModFlags;
+                       name = s.Name;
+               } else
+                       break;
+
+               if ((mod_flags & (Modifiers.PRIVATE|Modifiers.PROTECTED)) != 0){
+                       Report.Error (
+                               1527, lexer.Location, 
+                               "Namespace elements cant be explicitly " +
+                               "declared private or protected in `" + name + "'");
+               }
+               current_namespace.DeclarationFound = true;
+         }
+       ;
+
+identifier
+       : IDENTIFIER
+       | BINARY
+       | TEXT
+       | COMPARE
+       | EXPLICIT
+       | OFF
+       ;
+
+type_character
+       : PERCENT                       { $$ = TypeManager.system_int32_expr; }
+       | LONGTYPECHAR                  { $$ = TypeManager.system_int64_expr; }
+       | AT_SIGN                       { $$ = TypeManager.system_decimal_expr; }
+       | SINGLETYPECHAR                { $$ = TypeManager.system_single_expr; }
+       | NUMBER_SIGN                   { $$ = TypeManager.system_double_expr; }
+       | DOLAR_SIGN                    { $$ = TypeManager.system_string_expr; }
+       ;       
+       
+opt_type_character
+       : /* empty */                   { $$ = null; }
+       | type_character                { $$ = $1; }
+       ;
+       
+
+qualified_identifier
+       : identifier
+       {
+               $$ = new MemberName ((string) $1);
+       }
+       | qualified_identifier DOT identifier // FIXME: It should be qualified_identifier DOT identifier-or-keyword
+       {
+               $$ = new MemberName ((MemberName) $1, (string) $3, null);
+         }
+       ;
+       
+opt_imports_directives
+       : /* empty */
+       | imports_directives
+       ;
+
+imports_directives
+       : imports_directive 
+       | imports_directives imports_directive 
+       ;
+
+imports_directive
+       : IMPORTS imports_terms logical_end_of_line
+       ;
+
+imports_terms
+       : imports_term
+       | imports_terms COMMA imports_term
+       ;
+       
+imports_term
+       : namespace_or_type_name 
+       {
+               string name = ((MemberName) $1).GetName ();
+               current_namespace.Using (name, lexer.Location);
+       }
+       | identifier ASSIGN namespace_or_type_name 
+       {
+                 current_namespace.UsingAlias ((string) $1, (MemberName) $3, lexer.Location);
+       }
+       ;
+       
+
+opt_params
+       : /* empty */   { $$ = Parameters.EmptyReadOnlyParameters; }
+       | OPEN_PARENS CLOSE_PARENS      { $$ = Parameters.EmptyReadOnlyParameters; }
+       | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS    { $$ = $2; }
+       ;
+
+opt_attributes
+       : /* empty */
+         { 
+                 current_attributes = null;
+         }
+       | attribute_sections    
+         { 
+               $$ = $1; 
+               local_attrib_section_added = false;
+               current_attributes = (Attributes) $1;
+         }
+       ;
+
+attribute_sections
+       :  attribute_section    
+         { 
+               $$ = $1;
+               if ($1 == null) {
+                       expecting_local_attribs = false;
+                       expecting_global_attribs = false;
+                       break;
+               }
+               
+               if (expecting_local_attribs) {
+                       local_attrib_section_added = true;
+                       allow_global_attribs = false;
+
+                       $$ = new Attributes ((ArrayList) $1);
+               }       
+
+               if (expecting_global_attribs) {
+                       $$ = null;
+                       CodeGen.AddGlobalAttributes ((ArrayList) $1);
+               }
+
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
+         }
+       | attribute_sections  
+          {
+               $$ = lexer.Location;
+          }
+          attribute_section    
+         {
+               $$ = $1;
+               if ($3 != null) {
+                       ArrayList attrs = (ArrayList) $3;
+
+                       if (expecting_local_attribs) {
+                               if (local_attrib_section_added) {
+                                       expecting_local_attribs = false;
+                                       expecting_global_attribs = false;
+                                       Report.Error (30205, (Location) $2, "Multiple attribute sections may not be used; Coalesce multiple attribute sections in to a single attribute section");
+                                       break;
+                               }
+
+                               if ($1 == null)
+                                       $$ = new Attributes (attrs);
+                               else 
+                                       ((Attributes) $1).AddAttributes (attrs);
+
+                               local_attrib_section_added = true;
+                               allow_global_attribs = false;
+                       }
+
+                       if (expecting_global_attribs) {
+                               $$ = null;
+                               CodeGen.AddGlobalAttributes ((ArrayList) $3);
+                       }
+               }       
+
+               expecting_local_attribs = false;
+               expecting_global_attribs = false;
+         }
+       ;
+
+attribute_section
+       : OP_LT attribute_list OP_GT opt_end_of_stmt
+         {
+               $$ = null;
+               if ($2 != null) {
+                       if (expecting_global_attribs && !(bool) $4) {
+                               Report.Error (30205, lexer.Location, "End of statement expected");
+                               break;
+                       }
+                       
+                       if (expecting_local_attribs)  {
+                               if ((bool) $4) {
+                                       Report.Error (32035, lexer.Location, "Use a line continuation after the attribute specifier to apply it to the following statement.");
+                                       break;
+                               }
+                       }
+
+                       $$ = $2;
+               }
+         }
+       ; 
+
+opt_end_of_stmt
+       : /* empty */ { $$ = false; }
+       | end_of_stmt   { $$ = true; }
+       ;
+
+attribute_list
+       : attribute 
+         {
+               ArrayList attrs = null;
+               if ($1 != null) {
+                       attrs = new ArrayList ();
+                       attrs.Add ($1);
+               }
+               $$ = attrs;
+         }     
+       | attribute_list COMMA attribute
+         {
+               ArrayList attrs = null;
+               
+               if ($3 != null) {
+                       attrs = ($1 == null) ? new ArrayList () : (ArrayList) $1;
+                       attrs.Add ($3);
+               }
+
+               $$ = attrs;
+         }     
+       ;
+
+attribute 
+       :  namespace_or_type_name
+          {
+               $$ = lexer.Location;
+          }
+          opt_attribute_arguments
+          {
+               $$ = null;
+               
+               if (expecting_global_attribs)
+                       Report.Error (32015, (Location) $2, "Expecting Assembly or Module attribute specifiers");
+               else {
+                       expecting_local_attribs = true;
+                       MemberName mname = (MemberName) $1;
+                       string name = mname.GetName ();
+
+                       $$ = new Attribute (null, name, (ArrayList) $3,
+                                           (Location) $2);
+               }
+          }
+         | attribute_target_specifier 
+           {
+               $$ = lexer.Location;
+           }
+           COLON 
+           namespace_or_type_name
+          {
+                 $$ = lexer.Location;
+          }
+          opt_attribute_arguments
+          {
+               $$ = null;
+
+               string attribute_target = (string) $1;
+               if (attribute_target != "assembly" && attribute_target != "module") {
+                       Report.Error (29999, lexer.Location, "`" + (string)$1 + "' is an invalid attribute modifier");
+                       break;
+               }
+               if (!allow_global_attribs) {
+                       Report.Error (30637, (Location) $2, "Global attribute statements must precede any declarations in a file");
+                       break;
+               }
+
+               if (expecting_local_attribs) {
+                       Report.Error (30183, (Location) $2, "Global attributes cannot be combined with local attributes");
+                       break;
+               }                       
+
+               expecting_global_attribs = true;
+
+               MemberName mname = (MemberName) $4;
+               string aname = mname.GetName ();
+
+               $$ = new Attribute (attribute_target, aname, (ArrayList) $6, (Location) $5);
+           }   
+       ;
+
+
+attribute_target_specifier
+       :  ASSEMBLY     { $$ = "assembly"; }
+       | MODULE        { $$ = "module"; }
+       | namespace_or_type_name
+       ;
+       
+                       
+opt_attribute_arguments
+       : /* empty */   { $$ = null; }
+       | OPEN_PARENS opt_attribute_arguments_list CLOSE_PARENS
+         {
+               $$ = $2;
+         }     
+       ;
+
+opt_attribute_arguments_list
+       : /* empty */
+       | attribute_arguments_list
+       ;               
+       
+attribute_arguments_list
+       : positional_argument_list
+         {
+               ArrayList args = new ArrayList (4);
+               args.Add ($1);
+       
+               $$ = args;
+         }
+        | positional_argument_list COMMA named_argument_list
+         {
+               ArrayList args = new ArrayList (4);
+               args.Add ($1);
+               args.Add ($3);
+
+               $$ = args;
+         }
+        | named_argument_list
+         {
+               ArrayList args = new ArrayList (4);
+               args.Add (null);
+               args.Add ($1);
+               
+               $$ = args;
+         }
+        ;
+
+positional_argument_list
+       : constant_expression
+         {
+               ArrayList args = new ArrayList ();
+               args.Add (new Argument ((Expression) $1, Argument.AType.Expression));
+
+               $$ = args;
+         }
+        | positional_argument_list COMMA constant_expression
+        {
+               ArrayList args = (ArrayList) $1;
+               args.Add (new Argument ((Expression) $3, Argument.AType.Expression));
+
+               $$ = args;
+        }
+        ;
+
+named_argument_list
+       : named_argument
+         {
+               ArrayList args = new ArrayList ();
+               args.Add ($1);
+
+               $$ = args;
+         }
+        | named_argument_list COMMA named_argument
+         {       
+               ArrayList args = (ArrayList) $1;
+               args.Add ($3);
+
+               $$ = args;
+         }
+        ;
+
+named_argument
+       : identifier ATTR_ASSIGN constant_expression //FIXME: It should be identifier_or_keyword ATTR_ASSIGN constant_expression
+         {
+               $$ = new DictionaryEntry (
+                       (string) $1, 
+                       new Argument ((Expression) $3, Argument.AType.Expression));
+         }
+       ;
+                               
+namespace_declaration
+       : NAMESPACE qualified_identifier logical_end_of_line
+       {
+               if (current_attributes != null) {
+                       Report.Error(1518, Lexer.Location, "Attributes cannot be applied to namespaces."
+                                       + " Expected class, delegate, enum, interface, or struct");
+               }
+
+               MemberName name = (MemberName) $2;
+
+               if ((current_namespace.Parent != null) && (name.Left != null)) {
+                       Report.Error (134, lexer.Location,
+                                     "Cannot use qualified namespace names in nested " +
+                                     "namespace declarations");
+               }
+
+               current_namespace = new NamespaceEntry (
+                       current_namespace, file, name.GetName (), lexer.Location);
+         } 
+         opt_declarations
+         END NAMESPACE logical_end_of_line
+         { 
+               current_namespace = current_namespace.Parent;
+         }
+
+       ;
+
+declaration_qualifiers
+       : opt_attributes opt_modifiers 
+       ;
+
+type_spec_declaration
+       : class_declaration
+       | module_declaration
+       | interface_declaration
+       | delegate_declaration
+       | struct_declaration
+       | enum_declaration
+       ;
+
+class_declaration
+       : CLASS identifier logical_end_of_line 
+         {
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
+               MemberName name = MakeName (new MemberName ((string) $2));
+               int mod_flags = current_modifiers;
+
+
+               current_class = new Class (current_namespace, current_container, name,
+                                          mod_flags, (Attributes) current_attributes, lexer.Location);
+
+
+               current_container = current_class;
+               RootContext.Tree.RecordDecl (name.GetName (true), current_class);
+         }
+         opt_inherits opt_implements
+
+         {
+               ArrayList bases = (ArrayList) $5;
+               ArrayList ifaces = (ArrayList) $6;
+
+               if (ifaces != null){
+                       if (bases != null)      
+                               bases.AddRange(ifaces);
+                       else
+                               bases = ifaces;
+               }
+
+               if (bases != null) {
+                       if (current_class.Name == "System.Object") {
+                               Report.Error (537, current_class.Location,
+                                             "The class System.Object cannot have a base " +
+                                             "class or implement an interface.");
+                       }
+                       current_class.Bases = (ArrayList) bases;
+               }
+
+               current_class.Register ();
+         }
+         opt_class_member_declarations
+         END CLASS logical_end_of_line
+         {
+               $$ = current_class;
+
+               current_container = current_container.Parent;
+               current_class = current_container;
+         }
+       ;
+
+opt_inherits
+       : /* empty */                           { $$ = null; }
+       | INHERITS type_list logical_end_of_line        { $$ = $2; }
+       ;
+
+opt_implements
+       : /* empty */                           { $$ = null; }
+       | IMPLEMENTS type_list logical_end_of_line      { $$ = $2; }
+       ;
+
+opt_modifiers
+       : /* empty */           
+       { 
+               $$ = (int) 0; 
+               current_modifiers = 0; 
+       }
+       | modifiers             
+       { 
+               $$ = $1; 
+               current_modifiers = (int) $1; 
+       }
+       ;
+       
+modifiers
+       : modifier
+       | modifiers modifier
+         { 
+               int m1 = (int) $1;
+               int m2 = (int) $2;
+
+               if ((m1 & m2) != 0) {
+                       Location l = lexer.Location;
+                       Report.Error (1004, l, "Duplicate modifier: `" + Modifiers.Name (m2) + "'");
+               }
+               $$ = (int) (m1 | m2);
+         }
+        ;
+
+modifier
+       : PUBLIC                        { $$ = Modifiers.PUBLIC; }
+       | PROTECTED                     { $$ = Modifiers.PROTECTED; }
+       | PRIVATE                       { $$ = Modifiers.PRIVATE; }
+       | SHARED                        { $$ = Modifiers.STATIC; }
+       | FRIEND                        { $$ = Modifiers.INTERNAL; }
+       | NOTINHERITABLE                { $$ = Modifiers.SEALED; } 
+       | OVERRIDABLE                   { $$ = Modifiers.VIRTUAL; }
+       | NOTOVERRIDABLE                { $$ = Modifiers.NONVIRTUAL; }
+       | OVERRIDES                     { $$ = Modifiers.OVERRIDE; }
+       | OVERLOADS                     { $$ = Modifiers.NEW; }
+       | SHADOWS                       { $$ = Modifiers.SHADOWS; }
+       | MUSTINHERIT                   { $$ = Modifiers.ABSTRACT; }
+       | READONLY                      { $$ = Modifiers.READONLY; }
+       | DEFAULT                       { $$ = Modifiers.DEFAULT; }
+       | WRITEONLY                     { $$ = Modifiers.WRITEONLY; }
+       ;
+
+module_declaration
+       : MODULE identifier logical_end_of_line
+         { 
+               MemberName name = MakeName(new MemberName ((string) $2));
+               current_class = new VBModule (current_namespace, current_container, name, 
+                                           current_modifiers, current_attributes, lexer.Location);
+
+               current_container = current_class;
+               RootContext.Tree.RecordDecl(name.GetName (true), current_class);
+
+               current_class.Register ();
+         }
+         opt_module_member_declarations
+         END MODULE logical_end_of_line
+         {
+               $$ = current_class;
+//             FIXME: ?????
+//             TypeManager.AddStandardModule (current_class);
+
+               current_container = current_container.Parent;
+               current_class = current_container;
+         }
+       ;
+
+opt_module_member_declarations
+       : /* empty */
+       | module_member_declarations
+       ;
+
+module_member_declarations
+       : module_member_declaration
+       | module_member_declarations module_member_declaration
+       ;
+
+module_member_declaration
+       :  opt_attributes
+          opt_modifiers
+          { 
+               current_modifiers = ((int)$2) | Modifiers.STATIC; 
+               bool explicit_static = (((int) $2 & Modifiers.STATIC) > 0);
+               implicit_modifiers = (!explicit_static);
+          }
+
+          module_member_declarator
+          {
+               implicit_modifiers = false;
+               $$ = $3;
+          }
+       ;
+
+module_member_declarator
+       :  constructor_declaration
+       |  method_declaration
+       |  field_declaration
+//     |  withevents_declaration       /* This is a field but must be treated specially, see below */
+       |  constant_declaration
+       |  property_declaration                 
+       |  event_declaration
+       |  type_spec_declaration                        
+       ;
+
+       
+constant_declaration
+       : CONST constant_declarators logical_end_of_line
+       {
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+               
+               int modflags = (int) current_modifiers;
+               
+               // Structure members are Public by default                      
+               if ((current_container is Struct) && (modflags == 0))
+                       modflags = Modifiers.PUBLIC;                    
+
+               ArrayList consts = (ArrayList) $2;
+               if(consts.Count > 0) 
+               {
+                       VariableDeclaration.FixupTypes ((ArrayList) $2);
+                       VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
+
+                       foreach (VariableDeclaration constant in (ArrayList) $2){
+                               Location l = constant.Location;
+                               Const c = new Const (current_class, 
+                                                    (Expression) constant.type, 
+                                                    (String) constant.identifier, 
+                                                    (Expression) constant.expression_or_array_initializer, 
+                                                    modflags, current_attributes, l);
+
+                               current_container.AddConstant (c);
+                       }
+               }
+       }
+       ;
+          
+opt_class_member_declarations
+       : /* empty */
+       | class_member_declarations
+       ;
+
+class_member_declarations
+       : class_member_declaration
+       | class_member_declarations class_member_declaration
+       ;
+
+class_member_declaration
+       :  opt_attributes
+          opt_modifiers
+          class_member_declarator
+          {
+               $$ = $3;
+          }
+       ;
+
+class_member_declarator
+       :  field_declaration
+       |  constant_declaration
+       |  method_declaration
+       |  constructor_declaration
+       |  property_declaration                 
+       |  event_declaration
+//     |  withevents_declaration       /* This is a field but must be treated specially, see below */
+       |  type_spec_declaration
+       ;
+       
+       
+method_declaration
+       : sub_declaration
+       | func_declaration 
+//     | must_override_declaration
+       ;
+       
+// must_override_declaration
+//     : must_override_sub_declaration
+//     | must_override_func_declaration        
+//     ;
+       
+// must_override_sub_declaration
+//     : MUSTOVERRIDE SUB identifier opt_params opt_implement_clause logical_end_of_line
+//       {     
+// //          if (current_container is Module)
+// //                  Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
+                       
+//             if (current_container is Struct)
+//                     Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+               
+//             current_modifiers |= Modifiers.ABSTRACT;
+                                       
+//             Method method = new Method (TypeManager.system_void_expr, (int) current_modifiers, (string) $3,
+//                                         (Parameters) $4, null, (ArrayList) $5, lexer.Location);
+                                           
+//             if (!(current_container is Class))
+//                     Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");               
+                       
+//             $$ = method;                        
+//       }
+//     ;
+
+       
+// must_override_func_declaration
+//     : MUSTOVERRIDE FUNCTION identifier opt_type_character opt_params opt_type_with_ranks opt_implement_clause logical_end_of_line
+//       {     
+//             Expression ftype = ($6 == null) ? (($4 == null) ? TypeManager.  
+//                     system_object_expr : (Expression) $4 ) : (Expression) $6;
+
+//             if (current_container is Module)
+//                     Report.Error (433, "Methods in a Module cannot be declared 'MustOverride'.");
+                       
+//             if (current_container is Struct)
+//                     Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+                               
+//             current_modifiers |= Modifiers.ABSTRACT;
+                                                       
+//             Method method = new Method ((Expression) ftype, (int) current_modifiers, 
+//                                             (string) $3,(Parameters) $5, null, (ArrayList) $7, 
+//                                             lexer.Location);
+                                           
+//             if (!(current_container is Class))
+//                     Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
+                       
+//             $$ = method;                                    
+//       }     
+//     ;
+       
+
+sub_declaration
+       : SUB identifier opt_params 
+         {
+               MemberName name = new MemberName ((string) $2);
+
+               if ((current_container is Struct) && (current_modifiers == 0))
+                       current_modifiers = Modifiers.PUBLIC;           
+
+
+               GenericMethod generic = null;
+               Method method = new Method (current_class, generic, TypeManager.system_void_expr,
+                                           (int) current_modifiers, false, name, 
+                                           (Parameters) $3, (Attributes) current_attributes, 
+                                           lexer.Location);
+
+               current_local_parameters = (Parameters) $3;
+               $$ = method;
+
+               iterator_container = (IIteratorContainer) method;
+         }
+         opt_evt_handler opt_implement_clause logical_end_of_line 
+         // FIXME: opt_event_handler and opt_implements_clause are yet to be handled
+         begin_block
+         opt_statement_list 
+         end_block
+         END SUB logical_end_of_line
+         {
+               Method method = (Method) $4;
+               Block b = (Block) $10;
+               const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
+
+               if (b == null){
+                       if ((method.ModFlags & extern_abstract) == 0){
+                               Report.Error (
+                                       501, lexer.Location,  current_container.MakeName (method.Name) +
+                                       "must declare a body because it is not marked abstract or extern");
+                       }
+               } else {
+                       if ((method.ModFlags & Modifiers.EXTERN) != 0){
+                               Report.Error (
+                                       179, lexer.Location, current_container.MakeName (method.Name) +
+                                       " is declared extern, but has a body");
+                       }
+               }
+
+               method.Block = (ToplevelBlock) $10;
+               current_container.AddMethod (method);
+
+               current_local_parameters = null;
+               iterator_container = null;
+         }
+       ;
+
+func_declaration
+       : FUNCTION identifier opt_type_character
+         opt_params opt_type_with_ranks 
+         {
+               MemberName name =  new MemberName ((string) $2);
+               Expression rettype = ($5 == null) ? (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
+
+               GenericMethod generic = null;
+
+               Method method = new Method (current_class, generic, rettype, current_modifiers,
+                                           false, name,  (Parameters) $4, current_attributes,
+                                           lexer.Location);
+
+               current_local_parameters = (Parameters) $4;
+
+               $$ = method;
+               iterator_container = method;
+         }
+//       FIXME: opt_implement_clauses needs to be taken care of
+         opt_implement_clause logical_end_of_line
+         begin_block
+         { 
+               Method method = (Method) $6;
+
+               ArrayList retval = new ArrayList ();
+               retval.Add (new VariableDeclaration ((string) $2, method.Type, lexer.Location));
+               declare_local_variables (method.Type, retval, lexer.Location);
+         }       
+         opt_statement_list
+         end_block
+         END FUNCTION logical_end_of_line
+         {
+               Method method = (Method) $6;
+               Block b = (Block) $12;
+               const int extern_abstract = (Modifiers.EXTERN | Modifiers.ABSTRACT);
+
+               if (b == null){
+                       if ((method.ModFlags & extern_abstract) == 0){
+                               Report.Error (
+                                       501, lexer.Location,  current_container.MakeName (method.Name) +
+                                       "must declare a body because it is not marked abstract or extern");
+                       }
+               } else {
+                       if ((method.ModFlags & Modifiers.EXTERN) != 0){
+                               Report.Error (
+                                       179, lexer.Location, current_container.MakeName (method.Name) +
+                                       " is declared extern, but has a body");
+                       }
+               }
+
+               method.Block = (ToplevelBlock) b;
+               current_container.AddMethod (method);
+
+               current_local_parameters = null;
+               iterator_container = null;
+         }
+       ;               
+
+struct_declaration
+       : STRUCTURE identifier logical_end_of_line
+         opt_implement_clause
+         { 
+               MemberName name = MakeName (new MemberName ((string) $2));
+
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
+               current_class = new Struct (current_namespace, current_container, name, current_modifiers,
+                                           current_attributes, lexer.Location);
+
+               current_container = current_class;
+               RootContext.Tree.RecordDecl (name.GetName (true), current_class);
+
+               if ($4 != null)
+                       current_class.Bases = (ArrayList) $4;
+
+               current_class.Register ();
+         }
+         opt_struct_member_declarations
+         {
+               $$ = current_class;
+
+               current_container = current_container.Parent;
+               current_class = current_container;
+         }
+         END STRUCTURE logical_end_of_line
+       ;
+
+
+
+// FIXME: logical_end_of_line is actually part of the opt_implements_clause
+// This rule is temporary
+
+opt_logical_end_of_line
+       : /* empty */
+       | logical_end_of_line
+       ;
+
+
+opt_struct_member_declarations
+       : /* empty */
+       | struct_member_declarations
+       ;
+
+struct_member_declarations
+       : struct_member_declaration
+       | struct_member_declarations struct_member_declaration
+       ;
+
+struct_member_declaration
+       : opt_modifiers
+         struct_member_declarator
+       ;
+       
+struct_member_declarator       
+       : field_declaration
+       | constant_declaration
+       | constructor_declaration
+       | method_declaration
+//     | property_declaration
+       | event_declaration
+       | type_spec_declaration
+
+       
+//      * This is only included so we can flag error 575:
+//      * destructors only allowed on class types
+//     | destructor_declaration
+       ;
+       
+// event_declaration
+//     : EVENT identifier AS type opt_implement_clause logical_end_of_line
+//       {
+//             VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
+
+//             Event e = new Event ((Expression) $4, var.identifier, 
+//                                  null, current_modifiers, 
+//                                  current_attributes, (ArrayList) $5,
+//                                  lexer.Location);
+
+//             CheckDef (current_container.AddEvent (e), e.Name, e.Location);
+//       }
+//     | EVENT identifier opt_params opt_implement_clause logical_end_of_line
+//       {
+//             string delName = null;
+
+//             if ($4 == null) {
+//                     delName = (string) $2;
+//                     delName = delName + "EventHandler";
+//                     Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
+//                                                     (current_container, TypeManager.system_void_expr, 
+//                                                     (int) current_modifiers, MakeName(delName), (Parameters) $3, 
+//                                                     (Attributes) current_attributes, lexer.Location);
+                                                         
+//                     del.Namespace = current_namespace;
+//                     CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
+//             } else {
+//                     ArrayList impls = (ArrayList) $4;
+//                     if (impls.Count > 1) {
+//                             string expstr = "Event '" + ((Expression) impls[1]).ToString () +
+//                                     "' can not be implemented with Event '" +
+//                                     (string) $2 + "', since it's delegate type does not match " +
+//                                     "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
+//                             Report.Error (31407, lexer.Location, expstr);
+//                     }                       
+//                     Expression impl = (Expression) impls[0];  
+//                     delName = impl.ToString();
+//                     delName = delName.Substring (delName.LastIndexOf(".") + 1);
+//                     delName = delName + "EventHandler";
+//             }
+               
+//             Event e = new Event (DecomposeQI (delName, lexer.Location),
+//                                      (string) $2, 
+//                                  null, current_modifiers, 
+//                                  current_attributes, (ArrayList) $4, 
+//                                  lexer.Location);
+
+//             CheckDef (current_container.AddEvent (e), e.Name, e.Location);
+//       }
+//     ;
+       
+
+
+event_declaration
+       : EVENT identifier AS type opt_implement_clause logical_end_of_line
+         {
+               VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
+
+               MemberName name = new MemberName ((string) $2);
+
+               Event e = new EventField (current_class, (Expression) $4, current_modifiers, false, name,
+                                         var.expression_or_array_initializer, current_attributes,
+                                         lexer.Location);
+
+               current_container.AddEvent (e);
+         }
+
+//     | EVENT identifier opt_params opt_implement_clause logical_end_of_line
+//       {
+//             string delName = null;
+
+//             if ($4 == null) {
+//                     delName = (string) $2;
+//                     delName = delName + "EventHandler";
+//                     Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
+//                                                     (current_container, TypeManager.system_void_expr, 
+//                                                     (int) current_modifiers, MakeName(delName), (Parameters) $3, 
+//                                                     (Attributes) current_attributes, lexer.Location);
+                                                         
+//                     del.Namespace = current_namespace;
+//                     CheckDef (current_container.AddDelegate (del), del.Name, lexer.Location);
+//             } else {
+//                     ArrayList impls = (ArrayList) $4;
+//                     if (impls.Count > 1) {
+//                             string expstr = "Event '" + ((Expression) impls[1]).ToString () +
+//                                     "' can not be implemented with Event '" +
+//                                     (string) $2 + "', since it's delegate type does not match " +
+//                                     "with the delegate type of '" + ((Expression) impls[0]).ToString () + "'";
+//                             Report.Error (31407, lexer.Location, expstr);
+//                     }                       
+//                     Expression impl = (Expression) impls[0];  
+//                     delName = impl.ToString();
+//                     delName = delName.Substring (delName.LastIndexOf(".") + 1);
+//                     delName = delName + "EventHandler";
+//             }
+               
+//             Event e = new Event (DecomposeQI (delName, lexer.Location),
+//                                      (string) $2, 
+//                                  null, current_modifiers, 
+//                                  current_attributes, (ArrayList) $4, 
+//                                  lexer.Location);
+
+//             CheckDef (current_container.AddEvent (e), e.Name, e.Location);
+//       }
+       ;
+
+enum_declaration
+       : ENUM identifier opt_type_spec logical_end_of_line
+         opt_enum_member_declarations 
+         { 
+               Location enum_location = lexer.Location;
+
+               Expression base_type = TypeManager.system_int32_expr;
+               if ((Expression) $3 != null)
+                       base_type = (Expression) $3;
+
+               ArrayList enum_members = (ArrayList) $5;
+               if (enum_members.Count == 0)
+                       Report.Error (30280, enum_location,
+                                     "Enum can not have empty member list");
+
+
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+                       
+               MemberName full_name = MakeName (new MemberName ((string) $2));
+               Enum e = new Enum (current_namespace, current_container, base_type, 
+                                  (int) current_modifiers, full_name, 
+                                  (Attributes) current_attributes, enum_location);
+               
+               foreach (VariableDeclaration ev in (ArrayList) $5) {
+                       e.AddEnumMember (ev.identifier, 
+                                        (Expression) ev.expression_or_array_initializer,
+                                        ev.Location, ev.OptAttributes, ev.DocComment);
+               }
+
+               string name = full_name.GetName ();
+               current_container.AddEnum (e);
+               RootContext.Tree.RecordDecl (name, e);
+
+         }
+         END ENUM logical_end_of_line
+       ;
+
+opt_enum_member_declarations
+       : /* empty */                   { $$ = new ArrayList (4); }
+       | enum_member_declarations      { $$ = $1; }
+       ;
+
+enum_member_declarations
+       : enum_member_declaration 
+         {
+               ArrayList l = new ArrayList ();
+
+               l.Add ($1);
+               $$ = l;
+         }
+       | enum_member_declarations  enum_member_declaration
+         {
+               ArrayList l = (ArrayList) $1;
+
+               l.Add ($2);
+
+               $$ = l;
+         }
+       ;
+
+enum_member_declaration
+       : opt_attributes identifier logical_end_of_line
+         {
+               $$ = new VariableDeclaration ((string) $2, null, lexer.Location, (Attributes) $1);
+         }
+       | opt_attributes identifier
+         {
+                 $$ = lexer.Location;
+         }
+          ASSIGN expression logical_end_of_line
+         { 
+               $$ = new VariableDeclaration ((string) $2, $5, lexer.Location, (Attributes) $1);
+         }
+       ;
+
+// interface_property_declaration
+//     : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
+//       {
+//             Expression ftype = ($5 == null) ? (($3 == null) ? 
+//                             TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
+
+//             current_local_parameters = (Parameters) $4;
+//             if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
+//                     get_parameters = current_local_parameters.Copy (lexer.Location);
+//                     set_parameters = current_local_parameters.Copy (lexer.Location);
+                       
+//                     Parameter implicit_value_parameter = new Parameter (
+//                                     ftype, "Value", Parameter.Modifier.NONE, null);
+                       
+//                     set_parameters.AppendParameter (implicit_value_parameter);
+//             }
+//             else
+//             {
+//                     get_parameters = Parameters.EmptyReadOnlyParameters;
+//                     set_parameters = new Parameters (null, null ,lexer.Location); 
+                       
+//                     Parameter implicit_value_parameter = new Parameter (
+//                                     ftype, "Value", Parameter.Modifier.NONE, null);
+                       
+//                     set_parameters.AppendParameter (implicit_value_parameter);
+//             }
+//             lexer.PropertyParsing = true;
+               
+//             Accessor get_block = new Accessor (null, null); 
+//             Accessor set_block = new Accessor (null, null); 
+                               
+//             Property prop = new Property ((Expression) ftype, (string) $2, current_modifiers,
+//                                      get_block, set_block, current_attributes, lexer.Location,
+//                                      null, get_parameters, set_parameters, null);
+    
+//             CheckDef (current_interface.AddProperty (prop), prop.Name, lexer.Location);
+               
+//             get_implicit_value_parameter_type = null;
+//             set_implicit_value_parameter_type = null;
+//             get_parameters = null;
+//             set_parameters = null;
+//             current_local_parameters = null;                        
+//       }
+//     ;
+       
+// interface_event_declaration
+//     : EVENT identifier AS type logical_end_of_line
+//       {
+//             VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
+
+//             Event e = new Event ((Expression) $4, var.identifier, 
+//                                  null, current_modifiers, 
+//                                  current_attributes, lexer.Location);
+
+//             CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
+
+//       }
+//     | EVENT identifier opt_params logical_end_of_line
+//       {
+//             string delName = (string) $2;
+//             delName = delName + "EventHandler";
+//             int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
+//         Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
+//                                             (current_container, TypeManager.system_void_expr, 
+//                                          (int) delModifiers, MakeName(delName), (Parameters) $3, 
+//                                          (Attributes) current_attributes, lexer.Location);
+                                                 
+//             del.Namespace = current_namespace;
+//             CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
+         
+//             Event e = new Event (DecomposeQI (delName, lexer.Location),
+//                                      (string) $2, 
+//                                  null, current_modifiers, 
+//                                  current_attributes, lexer.Location);
+
+//             CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
+//       }
+//     ;
+
+
+
+//FIXME: This apparently doesn't seem to emit the right code with property 
+//having opt_property_parameters defined
+
+interface_property_declaration
+       : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
+         {
+               get_implicit_value_parameter_type  = 
+                       ($5 == null) ? (($3 == null) ? 
+                               TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
+
+               current_local_parameters = (Parameters) $4;
+               if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
+                       get_parameters = current_local_parameters.Copy (lexer.Location);
+                       set_parameters = current_local_parameters.Copy (lexer.Location);
+                       
+                       Parameter implicit_value_parameter = new Parameter (
+                                       get_implicit_value_parameter_type, "Value", Parameter.Modifier.NONE, null);
+                       
+                       set_parameters.AppendParameter (implicit_value_parameter);
+               }
+               else
+               {
+                       get_parameters = Parameters.EmptyReadOnlyParameters;
+                       set_parameters = new Parameters (null, null ,lexer.Location); 
+                       
+                       Parameter implicit_value_parameter = new Parameter (
+                                       get_implicit_value_parameter_type, "Value", Parameter.Modifier.NONE, null);
+                       
+                       set_parameters.AppendParameter (implicit_value_parameter);
+               }
+               lexer.PropertyParsing = true;
+               
+               Location loc = lexer.Location;
+               MemberName name = new MemberName ((string) $2);
+
+               Accessor get_block = new Accessor (null, 0, null, loc); 
+               Accessor set_block = new Accessor (null, 0, null, loc); 
+
+               Property prop = new Property (current_class, get_implicit_value_parameter_type, 
+                                    (int) current_modifiers, true,
+                                    name, current_attributes, 
+                                    get_parameters, get_block, 
+                                    set_parameters, set_block, lexer.Location);
+               
+               current_container.AddProperty (prop);
+               
+               get_implicit_value_parameter_type = null;
+               set_implicit_value_parameter_type = null;
+               get_parameters = null;
+               set_parameters = null;
+               current_local_parameters = null;                        
+         }
+       ;
+
+
+// interface_event_declaration
+//     : EVENT identifier AS type logical_end_of_line
+//       {
+//             VariableDeclaration var = new VariableDeclaration ((string) $2, (Expression) $4, lexer.Location);
+
+//             Event e = new Event ((Expression) $4, var.identifier, 
+//                                  null, current_modifiers, 
+//                                  current_attributes, lexer.Location);
+
+//             CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
+
+//       }
+//     | EVENT identifier opt_params logical_end_of_line
+//       {
+//             string delName = (string) $2;
+//             delName = delName + "EventHandler";
+//             int delModifiers = (current_modifiers & ~Modifiers.ABSTRACT);
+//         Mono.MonoBASIC.Delegate del = new Mono.MonoBASIC.Delegate 
+//                                             (current_container, TypeManager.system_void_expr, 
+//                                          (int) delModifiers, MakeName(delName), (Parameters) $3, 
+//                                          (Attributes) current_attributes, lexer.Location);
+                                                 
+//             del.Namespace = current_namespace;
+//             CheckDef (current_interface.AddDelegate (del), del.Name, lexer.Location);
+         
+//             Event e = new Event (DecomposeQI (delName, lexer.Location),
+//                                      (string) $2, 
+//                                  null, current_modifiers, 
+//                                  current_attributes, lexer.Location);
+
+//             CheckDef (current_interface.AddEvent (e), e.Name, e.Location);
+//       }
+//     ;
+
+interface_declaration
+       : INTERFACE identifier logical_end_of_line
+         {
+               MemberName name = new MemberName ((string) $2);
+
+               current_class = new Interface (current_namespace, current_container, 
+                                              name, (int) current_modifiers, 
+                                              (Attributes) current_attributes, lexer.Location);
+
+               current_container = current_class;
+               RootContext.Tree.RecordDecl (name.GetName (true), current_class);
+
+         }
+         opt_interface_base
+         {
+               current_class.Bases = (ArrayList) $5;
+               current_class.Register ();
+         }
+         interface_body
+         {
+               $$ = current_class;
+
+               current_container = current_container.Parent;
+               current_class = current_container;
+         }
+         END INTERFACE logical_end_of_line
+       ;
+
+opt_interface_base
+       : /* empty */                     { $$ = null; }
+       | interface_bases                 { $$ = $1; }
+       ;
+
+interface_bases
+       : interface_base
+       | interface_bases interface_base
+         {
+               ArrayList bases = (ArrayList) $1;
+               bases.AddRange ((ArrayList) $2);
+               $$ = bases;
+         }
+       ;
+
+interface_base
+       : INHERITS type_list logical_end_of_line  { $$ = $2; }
+       ;
+
+interface_body
+       : opt_interface_member_declarations
+       ;
+
+opt_interface_member_declarations
+       : /* empty */
+       | interface_member_declarations
+       ;
+
+interface_member_declarations
+       : interface_member_declaration
+       | interface_member_declarations interface_member_declaration
+       ;
+
+interface_member_declaration
+       : opt_attributes opt_modifiers interface_member_declarator
+       ;
+       
+interface_member_declarator
+       : interface_method_declaration  
+         { 
+               Method m = (Method) $1;
+
+               current_container.AddMethod (m);
+         }
+       | interface_property_declaration        
+//     | interface_event_declaration 
+       ;
+
+interface_method_declaration
+       : SUB identifier opt_params logical_end_of_line
+         {
+               MemberName name = (MemberName) new MemberName ((string) $2);
+
+               GenericMethod generic = null;
+
+               $$ = new Method (current_class, generic, TypeManager.system_void_expr, 
+                                (int) current_modifiers, true, name, (Parameters) $3,  
+                                (Attributes) current_attributes, lexer.Location);
+         }
+
+       | FUNCTION identifier opt_type_character opt_params opt_type_with_ranks logical_end_of_line
+         {
+               MemberName name = new MemberName ((string) $2);
+               Expression return_type = ($5 == null) ? 
+                       (($3 == null) ? TypeManager.system_object_expr : (Expression) $3 ) 
+                       : (Expression) $5;
+
+               GenericMethod generic = null;
+               $$ = new Method (current_class, generic, return_type, (int) current_modifiers, 
+                                true, name, (Parameters) $4, (Attributes) current_attributes,
+                                lexer.Location);
+         }
+       ;
+
+property_declaration
+       : non_abstract_propery_declaration
+//     | abstract_propery_declaration 
+       ;
+       
+// abstract_propery_declaration
+//     : MUSTOVERRIDE PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks logical_end_of_line
+//       {     
+//             Expression ftype = ($6 == null) ? (($4 == null) ? 
+//                             TypeManager.system_object_expr : (Expression) $4 ) : (Expression) $6;
+
+//             if (current_container is Module)
+//                     Report.Error (30503, "Properties in a Module cannot be declared 'MustOverride'.");
+                       
+//             if (current_container is Struct)
+//                     Report.Error (435, "Methods in a Structure cannot be declared 'MustOverride'.");
+                               
+//             current_modifiers |= Modifiers.ABSTRACT;
+               
+//             current_local_parameters = (Parameters) $5;
+//             if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
+//                     get_parameters = current_local_parameters.Copy (lexer.Location);
+//                     set_parameters = current_local_parameters.Copy (lexer.Location);
+                       
+//                     Parameter implicit_value_parameter = new Parameter (
+//                                     ftype, "Value", Parameter.Modifier.NONE, null);
+                       
+//                     set_parameters.AppendParameter (implicit_value_parameter);
+//             }
+//             else
+//             {
+//                     get_parameters = Parameters.EmptyReadOnlyParameters;
+//                     set_parameters = new Parameters (null, null ,lexer.Location); 
+                       
+//                     Parameter implicit_value_parameter = new Parameter (
+//                                     ftype, "Value", Parameter.Modifier.NONE, null);
+                       
+//                     set_parameters.AppendParameter (implicit_value_parameter);
+//             }
+//             lexer.PropertyParsing = true;
+               
+//             Accessor get_block = new Accessor (null, null); 
+//             Accessor set_block = new Accessor (null, null); 
+                               
+//             Property prop = new Property ((Expression) ftype, (string) $3, current_modifiers, 
+//                                      get_block, set_block, current_attributes, lexer.Location,
+//                                      null, get_parameters, set_parameters, null);
+    
+//             if (!(current_container is Class))
+//                     Report.Error (9999, "THIS SHOULD NEVER HAPPEN!");
+                       
+//             CheckDef (current_container.AddProperty (prop), prop.Name, lexer.Location);
+               
+//             get_implicit_value_parameter_type = null;
+//             set_implicit_value_parameter_type = null;
+//             get_parameters = null;
+//             set_parameters = null;
+//             current_local_parameters = null;                                
+//       }     
+//     ;
+       
+non_abstract_propery_declaration
+         : PROPERTY identifier opt_type_character opt_property_parameters opt_type_with_ranks opt_implement_clause logical_end_of_line
+         {
+               get_implicit_value_parameter_type  = 
+                       ($5 == null) ? (($3 == null) ? 
+                               TypeManager.system_object_expr : (Expression) $3 ) : (Expression) $5;
+               get_implicit_value_parameter_name = (string) $2;
+               
+               current_local_parameters = (Parameters) $4;
+               if (current_local_parameters != Parameters.EmptyReadOnlyParameters) { 
+                       get_parameters = current_local_parameters.Copy (lexer.Location);
+                       set_parameters = current_local_parameters.Copy (lexer.Location);
+               }
+               else
+               {
+                       get_parameters = Parameters.EmptyReadOnlyParameters;
+                       set_parameters = new Parameters (null, null ,lexer.Location);           
+               }
+               lexer.PropertyParsing = true;
+
+               $$ = lexer.Location;
+         }
+         accessor_declarations 
+         END PROPERTY logical_end_of_line
+         {
+               lexer.PropertyParsing = false;
+
+               Property prop;
+               Pair pair = (Pair) $9;
+               
+               Accessor get_block = (Accessor) pair.First; 
+               Accessor set_block = (Accessor) pair.Second; 
+               
+               Location loc = lexer.Location;
+               MemberName name = new MemberName ((string) $2);
+
+               // FIXME: Implements Clause needs to be taken care of.
+
+               if ((current_container is Struct) && (current_modifiers == 0))
+                       current_modifiers = Modifiers.PUBLIC;                           
+
+
+               prop = new Property (current_class, get_implicit_value_parameter_type, 
+                                    (int) current_modifiers, false,
+                                    name, (Attributes) current_attributes, 
+                                    get_parameters, get_block, 
+                                    set_parameters, set_block, lexer.Location);
+               
+               current_container.AddProperty (prop);
+               get_implicit_value_parameter_type = null;
+               set_implicit_value_parameter_type = null;
+               get_parameters = null;
+               set_parameters = null;
+               current_local_parameters = null;
+         }
+       ;
+
+opt_property_parameters
+       : /* empty */
+         {
+               $$ = Parameters.EmptyReadOnlyParameters;
+         }
+       | OPEN_PARENS opt_formal_parameter_list CLOSE_PARENS
+         {
+               $$ = $2;
+         }
+       ;
+       
+opt_implement_clause
+       : /* empty */
+         {
+               $$ = null;
+         }
+       | IMPLEMENTS implement_clause_list
+         {
+               $$ = $2;
+         }
+       ;
+       
+implement_clause_list
+       : qualified_identifier
+         {
+                 MemberName mname = (MemberName) $1;
+                 ArrayList impl_list = new ArrayList ();
+                 impl_list.Add (mname.GetTypeExpression (lexer.Location));
+                 $$ = impl_list;
+         }     
+       | implement_clause_list COMMA qualified_identifier
+         {
+                 MemberName mname = (MemberName) $3;
+                 ArrayList impl_list = (ArrayList) $1;
+                 impl_list.Add (mname.GetTypeExpression (lexer.Location));
+                 $$ = impl_list;
+         }     
+       ;
+
+accessor_declarations
+       : get_accessor_declaration opt_set_accessor_declaration
+         { 
+               $$ = new Pair ($1, $2);
+         }
+       | set_accessor_declaration opt_get_accessor_declaration
+         {
+               $$ = new Pair ($2, $1);
+         }
+       ;
+
+opt_get_accessor_declaration
+       : /* empty */                   { $$ = null; }
+       | get_accessor_declaration
+       ;
+
+opt_set_accessor_declaration
+       : /* empty */                   { $$ = null; }
+       | set_accessor_declaration
+       ;
+
+get_accessor_declaration
+       : opt_attributes GET logical_end_of_line
+         {
+               if ((current_modifiers & Modifiers.WRITEONLY) != 0)
+                       Report.Error (30023, "'WriteOnly' properties cannot have a 'Get' accessor");
+         
+               current_local_parameters = get_parameters;
+               
+               lexer.PropertyParsing = false;
+               
+         }
+         begin_block
+         {
+               ArrayList retval = new ArrayList ();
+               retval.Add (new VariableDeclaration (get_implicit_value_parameter_name, get_implicit_value_parameter_type, lexer.Location));
+               declare_local_variables (get_implicit_value_parameter_type, retval, lexer.Location);    
+         }
+         opt_statement_list
+         end_block
+         END GET logical_end_of_line
+         {
+               $$ = new Accessor ((ToplevelBlock) $8, (int) current_modifiers, 
+                                  (Attributes) $1, lexer.Location);
+
+               current_local_parameters = null;
+               lexer.PropertyParsing = true;
+         }
+       ;
+
+
+
+set_accessor_declaration
+       : opt_attributes SET opt_set_parameter logical_end_of_line
+         {
+        if ((current_modifiers & Modifiers.READONLY) != 0)
+                       Report.Error (30022, "'ReadOnly' properties cannot have a 'Set' accessor");
+                       
+               Parameter implicit_value_parameter = new Parameter (
+                       set_implicit_value_parameter_type, 
+                       set_implicit_value_parameter_name, 
+                       Parameter.Modifier.NONE, null);
+
+               set_parameters.AppendParameter (implicit_value_parameter);
+               current_local_parameters = set_parameters;
+
+               lexer.PropertyParsing = false;
+         }
+         begin_block
+         opt_statement_list
+         end_block
+         END SET logical_end_of_line
+         {
+               $$ = new Accessor ((ToplevelBlock) $8, (int) current_modifiers, 
+                                  (Attributes) $1, lexer.Location);
+               current_local_parameters = null;
+               lexer.PropertyParsing = true;
+         }
+       ;
+
+opt_set_parameter
+       : /* empty */
+       {
+               set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type; // TypeManager.system_object_expr;
+               set_implicit_value_parameter_name = "Value";
+       }       
+       |OPEN_PARENS CLOSE_PARENS
+       {
+               set_implicit_value_parameter_type = (Expression) get_implicit_value_parameter_type;
+               set_implicit_value_parameter_name = "Value";
+       }       
+       | OPEN_PARENS opt_parameter_modifier opt_identifier opt_type_with_ranks CLOSE_PARENS
+       {
+               Parameter.Modifier pm = (Parameter.Modifier)$2;
+               if ((pm | Parameter.Modifier.VAL) != 0)
+                       Report.Error (31065, 
+                               lexer.Location, 
+                               "Set cannot have a paremeter modifier other than 'ByVal'");
+                               
+               set_implicit_value_parameter_type = (Expression) $4;
+               
+               if (set_implicit_value_parameter_type.ToString () != get_implicit_value_parameter_type.ToString ())
+                       Report.Error (31064, 
+                               lexer.Location, 
+                               "Set value parameter type can not be different from property type");
+                               
+               if ($2 != null)
+                       set_implicit_value_parameter_name = (string) $3;
+               else
+                       set_implicit_value_parameter_name = "Value";
+       }
+       ;
+
+field_declaration
+       : opt_dim_stmt 
+         variable_declarators logical_end_of_line
+         {               
+               int mod = (int) current_modifiers;
+
+               VariableDeclaration.FixupTypes ((ArrayList) $2);
+               VariableDeclaration.FixupArrayTypes ((ArrayList) $2);
+               
+//             if (current_container is Module)
+//                     mod = mod | Modifiers.STATIC;
+                       
+               // Structure members are Public by default                      
+               if ((current_container is Struct) && (mod == 0))
+                       mod = Modifiers.PUBLIC;                 
+               
+               if ((mod & Modifiers.Accessibility) == 0)
+                       mod |= Modifiers.PRIVATE;
+                                       
+               foreach (VariableDeclaration var in (ArrayList) $2){
+                       Location l = var.Location;
+                       Field field = new Field (current_class, var.type, mod, 
+                                                var.identifier, var.expression_or_array_initializer, 
+                                                (Attributes) null, l);
+
+                       current_container.AddField (field);
+               }
+         }
+       ;
+
+       
+// withevents_declaration
+//     : opt_dim_stmt WITHEVENTS variable_declarators logical_end_of_line
+//       {
+//             // Module members are static by default, but delegates *can't* be declared static
+//             // so we must fix it, if mbas was the one actually responsible for this
+//             // instead of triggering an error.
+//             if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+//                     current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+         
+//             /* WithEvents Fields must be resolved into properties
+//                with a bit of magic behind the scenes */
+                 
+//             VariableDeclaration.FixupTypes ((ArrayList) $3);
+               
+//             foreach (VariableDeclaration var in (ArrayList) $3) {
+//                     // 1 - We create a private field
+//                     Location l = var.Location;
+//                     Property prop;
+//                     if ((current_modifiers & Modifiers.STATIC) > 0) 
+//                             Report.Error (30234, l, "'Static' is not valid on a WithEvents declaration.");
+                       
+//                     Field field = new Field (var.type, Modifiers.PRIVATE, "_" + var.identifier, 
+//                                              var.expression_or_array_initializer, 
+//                                              (Attributes) null, l);
+                                                
+//                     CheckDef (current_container.AddField (field), field.Name, l);   
+                       
+//                     // 2 - Public property
+                               
+//                     prop = BuildSimpleProperty (var.type, (string) var.identifier, 
+//                                             field, (int) current_modifiers, 
+//                                             (Attributes) current_attributes, l);
+                       
+//                     CheckDef (current_container.AddProperty (prop), prop.Name, l);
+//             }               
+//       }
+//     ;
+       
+opt_dim_stmt 
+       : /* empty */
+       | DIM
+       ; 
+               
+delegate_declaration
+       : DELEGATE SUB  
+         identifier OPEN_PARENS 
+         opt_formal_parameter_list
+         CLOSE_PARENS 
+         logical_end_of_line
+         {
+               Location l = lexer.Location;
+               MemberName name = MakeName (new MemberName ((string) $3));
+
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
+               Delegate del = new Delegate (current_namespace, current_container, TypeManager.system_void_expr,
+                                            current_modifiers, name, (Parameters) $5, current_attributes, l);
+
+               current_container.AddDelegate (del);
+               RootContext.Tree.RecordDecl (name.GetName (true), del);
+         }     
+       
+       | DELEGATE FUNCTION       
+         identifier OPEN_PARENS 
+         opt_formal_parameter_list
+         CLOSE_PARENS opt_type_with_ranks logical_end_of_line
+         {
+               Location l = lexer.Location;
+               MemberName name = MakeName (new MemberName ((string) $3));
+
+               if (implicit_modifiers && ((current_modifiers & Modifiers.STATIC) != 0))
+                       current_modifiers = (current_modifiers & ~Modifiers.STATIC);
+
+               Expression rettype = ($7 == null) ? TypeManager.system_object_expr : (Expression) $7;
+               Delegate del = new Delegate (current_namespace, current_container, rettype,
+                                            current_modifiers, name, (Parameters) $5, current_attributes, l);
+
+               current_container.AddDelegate (del);
+               RootContext.Tree.RecordDecl (name.GetName (true), del);
+         }     
+
+       ;
+
+
+opt_evt_handler
+       : /* empty */           {       $$ = null; }
+//       | HANDLES evt_handler         {       $$ = $2; }
+    ;
+
+// evt_handler
+//     : qualified_identifier
+//       {
+//             $$ = (Expression) DecomposeQI ((string)$1, lexer.Location);     
+//       }
+//     | base_access
+//       {
+//             $$ = $1;
+//       }
+//     | ME DOT qualified_identifier
+//       {
+//             $$ = (Expression) DecomposeQI ((string)$3, lexer.Location);     
+//       }
+//     /*| MYBASE DOT qualified_identifier
+//       {
+//             // FIXME: this is blatantly wrong and crash-prone
+//             $$ = (Expression) DecomposeQI ("MyBase." + (string)$4, lexer.Location);
+//       }*/
+//     ;
+
+
+constructor_declaration
+       : SUB NEW opt_params logical_end_of_line
+         {
+               current_local_parameters = (Parameters) $3;
+               $$ = new Constructor (current_class, current_container.Basename, 0, (Parameters) $3, 
+                                     (ConstructorInitializer) null, lexer.Location);
+         }
+         begin_block
+         opt_statement_list
+         end_block
+         { 
+               Constructor c = (Constructor) $5;
+               c.Block = (ToplevelBlock) $8;
+               c.ModFlags = (int) current_modifiers;
+               c.OptAttributes = current_attributes;
+
+               // FIXME: Some more error checking from mcs needs to be merged here ???
+               
+               c.Initializer = CheckConstructorInitializer (ref c.Block.statements);
+
+               current_container.AddConstructor(c);
+               current_local_parameters = null;
+         }
+         END SUB logical_end_of_line
+       ;
+
+opt_formal_parameter_list
+       : /* empty */                   
+         { 
+               $$ = Parameters.EmptyReadOnlyParameters; 
+         }
+       | formal_parameter_list 
+         { 
+               $$ = $1;        
+         }
+       ;
+       
+formal_parameter_list
+       : parameters            
+         { 
+               ArrayList pars_list = (ArrayList) $1;
+               Parameter [] pars = null; 
+               Parameter array_parameter = null;
+               int non_array_count = pars_list.Count;
+               if (pars_list.Count > 0 && (((Parameter) pars_list [pars_list.Count - 1]).ModFlags & Parameter.Modifier.PARAMS) != 0) {
+                       array_parameter = (Parameter) pars_list [pars_list.Count - 1];
+                       non_array_count = pars_list.Count - 1;
+               }
+               foreach (Parameter par in pars_list)
+                       if (par != array_parameter && (par.ModFlags & Parameter.Modifier.PARAMS) != 0) {
+                               Report.Error (30192, lexer.Location, "ParamArray parameters must be last");
+                               non_array_count = 0; 
+                               array_parameter = null;
+                               break;
+                       }
+               if (non_array_count > 0) {
+                       pars = new Parameter [non_array_count];
+                       pars_list.CopyTo (0, pars, 0, non_array_count);
+               }
+               $$ = new Parameters (pars, array_parameter, lexer.Location); 
+         } 
+       ;
+
+parameters
+       : parameter     
+         {
+               ArrayList pars = new ArrayList ();
+
+               pars.Add ($1);
+               $$ = pars;
+         }
+       | parameters COMMA parameter
+         {
+               ArrayList pars = (ArrayList) $1;
+
+               pars.Add ($3);
+               $$ = $1;
+         }
+       ;
+
+parameter
+       : opt_attributes
+         opt_parameter_modifier
+         identifier opt_type_character opt_rank_specifiers opt_type_with_ranks opt_variable_initializer
+         {
+               Parameter.Modifier pm = (Parameter.Modifier)$2;
+               bool opt_parm = ((pm & Parameter.Modifier.OPTIONAL) != 0);
+               Expression ptype;
+               
+               if (opt_parm && ($7 == null))
+                       Report.Error (30812, lexer.Location, "Optional parameters must have a default value");
+
+               if (!opt_parm && ($7 != null))
+                       Report.Error (32024, lexer.Location, "Non-Optional parameters should not have a default value");
+
+               if ((pm & Parameter.Modifier.PARAMS) != 0) {
+                       if ((pm & ~Parameter.Modifier.PARAMS) != 0)
+                               Report.Error (30667, lexer.Location, "ParamArray parameters must be ByVal");
+               }
+               
+               if ((pm & Parameter.Modifier.REF) !=0)
+                       pm |= Parameter.Modifier.ISBYREF;
+               
+               if ($4 != null && $6 != null && $4 != $6)
+                       Report.Error (30302, lexer.Location, "Type character conflicts with declared type."); // TODO: Correct error number and message text
+
+               ptype = (Expression)(($6 == null) ? (($4 == null) ? TypeManager.system_object_expr : $4) : $6);
+               if ($5 != null) {
+                       string t = ptype.ToString ();
+                       if (t.IndexOf('[') >= 0)
+                               Report.Error (31087, lexer.Location, "Array types specified in too many places");
+                       else    
+                               ptype = DecomposeQI (t + VariableDeclaration.BuildRanks ((ArrayList) $5, true, lexer.Location), lexer.Location);
+               }
+               if ((pm & Parameter.Modifier.PARAMS) != 0 && ptype.ToString ().IndexOf('[') < 0)
+                       Report.Error (30050, lexer.Location, "ParamArray parameters must be an array type");
+               $$ = new Parameter (ptype, (string) $3, pm,
+                                       (Attributes) $1, (Expression) $7, opt_parm);
+         }
+       ;
+       
+opt_parameter_modifier
+       : /* empty */           { $$ = Parameter.Modifier.VAL;  }
+       | parameter_modifiers   { $$ = $1;                      }
+       ;
+
+parameter_modifiers
+       : parameter_modifiers parameter_modifier        { $$ = (Parameter.Modifier)$1 | (Parameter.Modifier)$2; }
+       | parameter_modifier                            { $$ = $1;      }
+       ;
+       
+parameter_modifier
+       : BYREF                 { $$ = Parameter.Modifier.REF | Parameter.Modifier.ISBYREF; }
+       | BYVAL                 { $$ = Parameter.Modifier.VAL; }
+       | OPTIONAL              { $$ = Parameter.Modifier.OPTIONAL; } 
+       | PARAM_ARRAY           { $$ = Parameter.Modifier.PARAMS; } 
+       ;       
+
+opt_statement_list
+       : /* empty */
+       | statement_list end_of_stmt
+       ;
+
+statement_list
+       : statement 
+       | statement_list end_of_stmt statement
+       ;
+
+block
+       : begin_block 
+         opt_statement_list
+         end_block { $$ = $3; }
+       ;
+
+begin_block
+       : /* empty */
+       {
+                 if (current_block == null){
+                         current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, current_local_parameters, lexer.Location);
+                         top_current_block = current_block;
+                 } else {
+                 current_block = new Block (current_block, current_local_parameters,
+                                                lexer.Location, Location.Null);
+                 }
+       } 
+       ;
+
+
+end_block
+       : /* empty */
+         { 
+               while (current_block.Implicit)
+                       current_block = current_block.Parent;
+               $$ = current_block;
+               current_block.SetEndLocation (lexer.Location);
+               current_block = current_block.Parent;
+               if (current_block == null)
+                       top_current_block = null;
+         }
+       ;
+
+statement 
+         : declaration_statement
+           {
+                 if ($1 != null && (Block) $1 != current_block){
+                       current_block.AddStatement ((Statement) $1);
+                       current_block = (Block) $1;
+                 }
+           }
+         | embedded_statement
+           {
+                 Statement s = (Statement) $1;
+
+                 current_block.AddStatement ((Statement) $1);
+           } 
+//       | labeled_statement 
+         | ADDHANDLER prefixed_unary_expression COMMA ADDRESSOF expression
+           {
+               Location loc = lexer.Location;
+
+               ExpressionStatement expr = new CompoundAssign (Binary.Operator.Addition, 
+                                        (Expression) $2, (Expression) $5, loc);
+
+               Statement stmt = new StatementExpression (expr, loc); 
+
+               current_block.AddStatement (stmt);
+
+           }
+
+         | REMOVEHANDLER prefixed_unary_expression COMMA ADDRESSOF expression
+           {
+               Location loc = lexer.Location;
+
+               ExpressionStatement expr = new CompoundAssign (Binary.Operator.Subtraction, 
+                                        (Expression) $2, (Expression) $5, loc);
+
+               Statement stmt = new StatementExpression (expr, loc); 
+
+               current_block.AddStatement (stmt);
+
+           }
+         | RAISEEVENT identifier opt_raise_event_args  //OPEN_PARENS opt_argument_list CLOSE_PARENS
+           {
+             Location loc = lexer.Location;
+             MemberName mname = new MemberName ((string) $2);
+             Expression expr = mname.GetTypeExpression (loc);
+
+             Invocation inv_expr = new Invocation (expr, (ArrayList) $3, loc);
+             Statement stmt = new StatementExpression (inv_expr, loc); 
+             current_block.AddStatement (stmt);        
+           }
+//       /* | array_handling_statement */
+//       /* | empty_statement */
+//       | with_statement 
+//         {
+//               Statement s = (Statement) $1;
+
+//           current_block.AddStatement ((Statement) $1);
+//         }     
+         ;     
+       
+         
+opt_raise_event_args 
+       : /* empty */   { $$ = null; }
+       | OPEN_PARENS opt_argument_list CLOSE_PARENS
+         {
+               $$ = $2;
+         }
+       ;
+
+// label_name
+//     : identifier
+//     | LITERAL_INTEGER
+//     {
+//             $$ = $1.ToString();
+//     }
+//     ;
+
+// labeled_statement
+//     : label_name COLON
+//       {
+//             LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
+
+//             if (!current_block.AddLabel ((string) $1, labeled)){
+//                     Location l = lexer.Location;
+//                     Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
+//             }       
+//             current_block.AddStatement (labeled);
+//       }
+//     | label_name COLON
+//       {
+//             LabeledStatement labeled = new LabeledStatement ((string) $1, lexer.Location);
+
+//             if (!current_block.AddLabel ((string) $1, labeled)){
+//                     Location l = lexer.Location;
+//                     Report.Error (140, l, "The label '" + ((string) $1) + "' is a duplicate");
+//             }       
+//             current_block.AddStatement (labeled);
+//       }
+//       statement
+//     ;
+
+embedded_statement
+       : expression_statement
+       | selection_statement
+//     | iteration_statement
+       | try_statement
+       | synclock_statement
+       | jump_statement
+//     | array_handling_statement 
+       ;
+
+// /*        
+// empty_statement
+//     : end_of_stmt
+//       {
+//               $$ = new EmptyStatement ();
+//       }
+//     ;        
+// */
+
+// with_statement
+//     : WITH expression end_of_stmt /* was : WITH qualified_identifier end_of_stmt */
+//       {
+//             // was : Expression e = DecomposeQI ((string) $2, lexer.Location);
+//             Expression e = (Expression) $2;
+//             with_stack.Push(e);
+//             start_block();
+//       }
+//       opt_statement_list
+//       END WITH
+//       {
+//             Block b = end_block();
+//             with_stack.Pop();
+//             $$ = b;
+//       }
+//     ;
+       
+       
+// array_handling_statement
+//     : redim_statement
+//     | erase_statement
+//     ;
+       
+// redim_statement
+//     : REDIM opt_preserve redim_clauses
+//       {
+//             ArrayList list = (ArrayList) $3;
+//             ReDim r = new ReDim (list, (bool) $2, lexer.Location);
+//             $$ = r;
+
+//       }
+//     ;
+       
+// opt_preserve
+//     : /* empty */   { $$ = false; }
+//     | PRESERVE      { $$ = true;  }
+//     ;
+       
+// redim_clauses
+//     : redim_clause
+//       {
+//             ArrayList clauses = new ArrayList ();
+
+//             clauses.Add ($1);
+//             $$ = clauses;
+//       }
+//     | redim_clauses COMMA redim_clause
+//       {
+//             ArrayList clauses = (ArrayList) ($1);
+//             clauses.Add ($2);
+
+//             $$ = clauses;
+//       }
+//     ;
+
+// redim_clause
+//     : invocation_expression
+//       {
+//             Invocation i = (Invocation) $1;
+//             RedimClause rc = new RedimClause (i.expr, i.Arguments);
+//             $$ = rc;
+//       }
+//     ;
+
+// erase_statement
+//     : ERASE erase_clauses
+//     {
+//             ArrayList list = (ArrayList) $2;
+//             foreach(Expression e in list)
+//             {
+//                     Erase r = new Erase (e, lexer.Location);
+//                     $$ = r;
+//             }
+//     }
+//     ;
+
+// erase_clauses
+//     : erase_clause
+//       {
+//             ArrayList clauses = new ArrayList ();
+
+//             clauses.Add ($1);
+//             $$ = clauses;
+//       }
+//     | erase_clauses COMMA erase_clause
+//       {
+//             ArrayList clauses = (ArrayList) ($1);
+//             clauses.Add ($2);
+
+//             $$ = clauses;
+//       }
+//     ;
+
+// erase_clause
+//     : primary_expression
+//     ;       
+                       
+jump_statement
+       : /*break_statement
+       | continue_statement
+       | */return_statement
+       | goto_statement        
+       | throw_statement       
+//     | exit_statement
+//     | yield_statement
+       ;
+               
+goto_statement
+       : GOTO label_name  
+         {
+               $$ = new Goto (current_block, (string) $2, lexer.Location);
+         }
+       ;
+       
+throw_statement
+       : THROW opt_expression
+         {
+               $$ = new Throw ((Expression) $2, lexer.Location);
+         }
+       ;       
+                       
+// exit_statement
+//     : EXIT exit_type
+//       {
+//             $$ = new Exit ((ExitType)$2, lexer.Location);           
+//       }
+//     ;
+       
+// exit_type
+//     : DO            { $$ = ExitType.DO;             }
+//     | FOR           { $$ = ExitType.FOR;            }
+//     | WHILE         { $$ = ExitType.WHILE;          }
+//     | SELECT        { $$ = ExitType.SELECT;         }
+//     | SUB           { $$ = ExitType.SUB;            }
+//     | FUNCTION      { $$ = ExitType.FUNCTION;       }
+//     | PROPERTY      { $$ = ExitType.PROPERTY;       }
+//     | TRY           { $$ = ExitType.TRY;            }
+//     ;
+
+return_statement
+       : RETURN opt_expression 
+         {       
+               $$ = new Return ((Expression) $2, lexer.Location);
+         }
+       ;
+               
+// iteration_statement
+//     : while_statement
+//     | do_statement
+//     | for_statement
+//     | foreach_statement
+//     ;
+
+// foreach_statement
+//     : FOR EACH identifier opt_type_spec IN 
+//       {
+//             oob_stack.Push (lexer.Location);
+//       }       
+//       expression end_of_stmt
+//       {
+//             Location l = lexer.Location;            
+//             LocalVariableReference v = null;
+//             VariableInfo vi;
+
+//             if ($4 != null) 
+//             {
+//                     start_block();
+//                     VariableDeclaration decl = new VariableDeclaration ((string) $3, 
+//                                     (Expression) $4, null, lexer.Location, null);
+                       
+//                     vi = current_block.AddVariable (
+//                             (Expression) $4, decl.identifier, current_local_parameters, decl.Location);
+
+//                     Expression expr;
+//                     if (decl.expression_or_array_initializer is Expression)
+//                             expr = (Expression) decl.expression_or_array_initializer;
+//                     else if (decl.expression_or_array_initializer == null) 
+//                             expr = null;
+//                     else 
+//                     {
+//                             ArrayList init = (ArrayList) decl.expression_or_array_initializer;
+//                             expr = new ArrayCreation ((Expression) $4, "", init, decl.Location);
+//                     }
+               
+//                     v = new LocalVariableReference (current_block, decl.identifier, l);
+
+//                     if (expr != null) 
+//                     {
+//                             Assign a = new Assign (v, expr, decl.Location);
+//                             current_block.AddStatement (new StatementExpression (a, lexer.Location));
+//                     }
+//             }
+//             else
+//             {
+//                     vi = current_block.GetVariableInfo ((string) $3);
+
+//                     if (vi != null) {
+//                             // Get a reference to this variable.
+//                             v = new LocalVariableReference (current_block, (string) $3, l, vi, false);
+//                     }
+//                     else
+//                             Report.Error (451, "Name '" + (string) $3 + "' is not declared.");
+//             }
+               
+//             oob_stack.Push (v);
+//             start_block();  
+//       }       
+//       opt_statement_list
+//       NEXT opt_identifier
+//       {
+//             LocalVariableReference v = (LocalVariableReference) oob_stack.Pop ();
+//             Block foreach_block = end_block();
+//             Location l = (Location) oob_stack.Pop ();
+
+//             Foreach f = null;
+//             if (v != null)
+//                     f = new Foreach (null, v, (Expression) $7, foreach_block, l);
+               
+//             if ($4 != null)
+//             {
+//                     current_block.AddStatement (f);
+//                     $$ = end_block ();
+//             }
+//             else
+//                     $$ = f;
+//       }       
+//     ;
+
+// yield_statement 
+//     : YIELD expression
+//       {
+//             if (!UseExtendedSyntax)
+//             {
+//                     ReportError9998();
+//                     $$ = null;
+//             }
+// /*          else
+//                     if (iterator_container == null){
+//                             Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+//                             $$ = null;
+//                     } else {
+//                             iterator_container.SetYields ();
+//                             $$ = new Yield ((Expression) $2, lexer.Location);
+//                     } */
+//       }
+//     | YIELD STOP
+//       {
+//             if (!UseExtendedSyntax)
+//             {
+//                     ReportError9998();
+//                     $$ = null;
+//             }
+// /*          else
+//                     if (iterator_container == null){
+//                             Report.Error (204, lexer.Location, "yield statement can only be used within a method, operator or property");
+//                             $$ = null;
+//                     } else {
+//                             iterator_container.SetYields ();
+//                             $$ = new YieldBreak (lexer.Location);
+//                     } */
+//       }
+//     ;
+
+synclock_statement
+       : SYNCLOCK expression end_of_stmt
+         block
+         END SYNCLOCK
+         {
+               $$ = new Lock ((Expression) $2, (Statement) $4, lexer.Location);
+         }
+       ;
+
+try_statement
+       : try_catch
+       | try_catch_finally
+       ;
+                               
+                                       
+try_catch
+       : TRY end_of_stmt block opt_catch_clauses END TRY
+         {
+               Catch g = null;
+               
+               ArrayList c = (ArrayList)$4;
+               for (int i = 0; i < c.Count; ++i) {
+                       Catch cc = (Catch) c [i];
+                       if (cc.IsGeneral) {
+                               if (i != c.Count - 1)
+                                       Report.Error (1017, cc.loc, "Empty catch block must be the last in a series of catch blocks");
+                               g = cc;
+                               c.RemoveAt (i);
+                               i--;
+                       }
+               }
+
+               // Now s contains the list of specific catch clauses
+               // and g contains the general one.
+               
+               $$ = new Try ((Block) $3, c, g, null, ((Block) $3).loc);
+         }
+       ;       
+         
+try_catch_finally
+       : TRY end_of_stmt 
+         block 
+         opt_catch_clauses 
+         FINALLY end_of_stmt
+         block
+         END TRY
+         {
+               Catch g = null;
+               ArrayList s = new ArrayList (4);
+               ArrayList catch_list = (ArrayList) $4;
+
+               if (catch_list != null){
+                       foreach (Catch cc in catch_list) {
+                               if (cc.IsGeneral)
+                                       g = cc;
+                               else
+                                       s.Add (cc);
+                       }
+               }
+
+               $$ = new Try ((Block) $3, s, g, (Block) $7, ((Block) $3).loc);
+         }
+         ;             
+
+opt_catch_clauses
+       : /* empty */  {  $$ = null;  }
+        | catch_clauses
+       ;
+
+catch_clauses
+       : catch_clause 
+         {
+               ArrayList l = new ArrayList (4);
+
+               l.Add ($1);
+               $$ = l;
+         }
+       | catch_clauses catch_clause
+         {
+               ArrayList l = (ArrayList) $1;
+
+               l.Add ($2);
+               $$ = l;
+         }
+       ;
+
+opt_identifier
+       : /* empty */   {  $$ = null;  }
+       | identifier
+       ;
+
+// opt_when
+//     : /* empty */   {  $$ = null;  }
+//     | WHEN boolean_expression { $$ = $2; }
+//     ;
+       
+
+catch_clause 
+//     : CATCH opt_catch_args opt_when end_of_stmt
+       : CATCH opt_catch_args end_of_stmt
+       {
+               // FIXME: opt_when needs to be hnadled
+               Expression type = null;
+               string id = null;
+               
+               if ($2 != null) {
+                       DictionaryEntry cc = (DictionaryEntry) $2;
+                       type = (Expression) cc.Key;
+                       id   = (string) cc.Value;
+
+                       if (id != null){
+                               ArrayList one = new ArrayList (4);
+                               Location loc = lexer.Location;
+
+                               one.Add (new VariableDeclaration (id, type, loc));
+
+                               $1 = current_block;
+                               current_block = new Block (current_block);
+                               Block b = declare_local_variables (type, one, loc);
+                               current_block = b;
+                       }
+               }
+       }
+       block
+       {
+               Expression type = null;
+               string id = null;
+
+               if ($2 != null){
+                       DictionaryEntry cc = (DictionaryEntry) $2;
+                       type = (Expression) cc.Key;
+                       id   = (string) cc.Value;
+
+                       if ($1 != null){
+                               //
+                               // FIXME: I can change this for an assignment.
+                               //
+                               while (current_block != (Block) $1)
+                                       current_block = current_block.Parent;
+                       }
+               }
+
+
+               $$ = new Catch (type, id , (Block) $5, ((Block) $5).loc);
+       }
+    ;
+
+opt_catch_args
+       : /* empty */ {  $$ = null; }
+        | catch_args
+       ;         
+
+catch_args 
+        : identifier AS type
+        {
+                $$ = new DictionaryEntry ($3, $1); 
+       }
+        ;
+
+
+// do_statement
+//     : DO opt_do_construct end_of_stmt
+//       {
+//             start_block();
+//             oob_stack.Push (lexer.Location);
+//       }     
+//       opt_statement_list
+//       LOOP opt_do_construct
+//       {
+//             Expression t_before = (Expression) $2;
+//             Expression t_after = (Expression) $7;
+//             Expression t;
+
+//             if  ((t_before != null) && (t_after != null))
+//                     Report.Error (30238, "'Loop' cannot have a condition if matching 'Do' has one.");
+
+//             if ((t_before == null) && (t_after == null))
+//                     t = new BoolLiteral (true);
+//             else
+//                     t = (t_before != null) ? t_before : t_after;
+                       
+//             DoOptions test_type = (t_before != null) ? DoOptions.TEST_BEFORE : DoOptions.TEST_AFTER;
+               
+//             if (((do_type == DoOptions.WHILE) && (test_type == DoOptions.TEST_BEFORE)) ||
+//                 ((do_type == DoOptions.UNTIL) && (test_type == DoOptions.TEST_AFTER)))
+//                      t = new Unary (Unary.Operator.LogicalNot, (Expression) t, lexer.Location);
+                        
+//             $$ = new Do ((Statement) end_block(), (Expression) t, test_type, lexer.Location);
+//       }
+//       ;
+
+// opt_do_construct
+//     : /* empty */ { $$ = null; }
+//     | while_or_until boolean_expression
+//       {
+//             do_type = (DoOptions)$1;
+//             $$ = (Expression) $2;
+//       }
+//     ;
+
+// while_or_until
+//     : WHILE { $$ = DoOptions.WHILE; }
+//     | UNTIL { $$ = DoOptions.UNTIL; }
+//     ;
+
+while_statement
+       : WHILE
+       {
+               oob_stack.Push (lexer.Location);
+       }
+       boolean_expression end_of_stmt
+       begin_block
+       opt_statement_list
+       end_block
+       END WHILE
+       {
+               Location l = (Location) oob_stack.Pop ();
+               $$ = new While ((Expression) $3, (Statement) $7, l);
+       }
+       ;
+
+// for_statement
+//     : FOR identifier opt_type_spec ASSIGN expression TO expression opt_step end_of_stmt
+//       {
+//             if ($3 != null)
+//             {
+//                     start_block();
+//                     ArrayList VarDeclaration = new ArrayList ();
+//                     VarDeclaration.Add (new VariableDeclaration ((string) $2, 
+//                             (Expression) $3, null, lexer.Location, null));
+
+//                     DictionaryEntry de = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), VarDeclaration);
+//                     Block b = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
+//                     current_block = b;
+//             }
+//             oob_stack.Push (lexer.Location);                
+//             start_block();
+//       }
+//       opt_statement_list
+//       NEXT opt_identifier 
+//       {
+//                     Block inner_statement = end_block();
+//                     Location l = (Location) oob_stack.Pop ();
+//                     Expression for_var = (Expression) DecomposeQI ((string)$2, l);
+                       
+//             Expression assign_expr = new Assign (for_var, (Expression) $5, l);
+//             Expression test_expr =  new Binary (Binary.Operator.LessThanOrEqual,
+//                                                             for_var, (Expression) $7, l);
+//             Expression step_expr = new Assign (for_var, (Expression) new Binary (Binary.Operator.Addition,
+//                                              for_var, (Expression) $8, l), l);
+
+//             Statement assign_stmt = new StatementExpression ((ExpressionStatement) assign_expr, l);
+//             Statement step_stmt = new StatementExpression ((ExpressionStatement) step_expr, l);
+
+//             For f = new For (assign_stmt, test_expr, step_stmt, inner_statement, l);
+//                     if ($3 != null)
+//                     {
+//                             current_block.AddStatement (f);
+//                             $$ = end_block();
+//                     }
+//                     else
+//                             $$ = f;
+//       }
+//     ;
+
+// opt_step
+//     : /* empty */           { $$ = new IntLiteral ((Int32) 1); }
+//     | STEP expression       { $$ = $2; }
+//     ;
+
+selection_statement
+       : if_statement
+//     | select_statement
+       ;
+
+// if_statement
+//     : IF boolean_expression opt_then end_of_stmt 
+//       if_statement_rest
+// //  | IF boolean_expression THEN block opt_else_pre_embedded_statement
+// //  | IF boolean_expression else_pre_embedded_statement
+//     ;
+
+
+// FXIME: The rule for LineIfThenStatement needs to be still enabled
+// FIXME: The lexer.Location that is calculated may have to replaced with the most correct one
+
+if_statement
+       : IF boolean_expression opt_then end_of_stmt 
+         block
+         END IF
+         { 
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               $$ = new If ((Expression) $2, (Statement) $5, l);
+
+               if (RootContext.WarningLevel >= 3){
+                       if ($5 == EmptyStatement.Value)
+                               Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
+               }
+
+         }
+         
+       | IF boolean_expression opt_then end_of_stmt 
+         block
+         ELSE end_of_stmt 
+         block
+         END IF
+         {
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               $$ = new If ((Expression) $2, (Statement) $5, (Statement) $8, l);
+         }     
+       
+       | IF boolean_expression opt_then end_of_stmt 
+         block
+         else_if_statement_rest 
+         {
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               $$ = new If ((Expression) $2, (Statement) $5, (Statement) $6, l);
+         }     
+       ;
+
+else_if_statement_rest
+       : ELSEIF boolean_expression opt_then end_of_stmt 
+         block
+         END IF
+         { 
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               $$ = new If ((Expression) $2, (Statement) $5, l);
+
+               if (RootContext.WarningLevel >= 3){
+                       if ($5 == EmptyStatement.Value)
+                               Report.Warning (642, lexer.Location, "Possible mistaken empty statement");
+               }
+
+         }
+
+       | ELSEIF boolean_expression opt_then end_of_stmt 
+         block
+         ELSE end_of_stmt 
+         block
+         END IF        
+         {
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               $$ = new If ((Expression) $2, (Statement) $5, (Statement) $8, l);
+         }     
+
+       | ELSEIF boolean_expression opt_then end_of_stmt 
+         block
+         else_if_statement_rest 
+         {
+               oob_stack.Push (lexer.Location);          
+               Location l = (Location) oob_stack.Pop ();
+
+               $$ = new If ((Expression) $2, (Statement) $5, (Statement) $6, l);
+         }     
+       ;
+
+
+// opt_else_pre_embedded_statement
+//     : /* empty */
+//     | else_pre_embedded_statement
+//     ;
+       
+// else_pre_embedded_statement 
+//     : ELSE
+//       {
+//             Block bl = end_block(); 
+//         tmp_blocks.Push(bl); 
+        
+//             start_block();
+//       }
+//     | ELSE embedded_statement 
+//       {
+//             Block bl = end_block(); 
+//         tmp_blocks.Push(bl); 
+        
+//             start_block();
+//             Statement s = (Statement) $2;
+//             current_block.AddStatement ((Statement) $2);
+//       } 
+//     ;       
+
+       
+opt_then
+       : /* empty */
+       | THEN
+       ;
+       
+
+// select_statement
+//     : SELECT opt_case expression end_of_stmt
+//       { 
+//             oob_stack.Push (lexer.Location);
+//             switch_stack.Push (current_block);
+//       }     
+//       opt_case_sections
+//       END SELECT 
+//       {
+//             $$ = new Switch ((Expression) $3, (ArrayList) $6, (Location) oob_stack.Pop ());
+//             current_block = (Block) switch_stack.Pop ();
+//       }       
+//     ;
+
+// opt_case_sections
+//     : /* empty */   { $$ = null; }
+//     | case_sections { $$ = $1; }
+//     ;
+       
+// case_sections
+//     : case_sections case_section
+//       {
+//             ArrayList sections = (ArrayList) $1;
+
+//             sections.Add ($2);
+//             $$ = sections;
+//       }
+//     | case_section
+//       {
+//             ArrayList sections = new ArrayList (4);
+
+//             sections.Add ($1);
+//             $$ = sections;
+//       }
+//     ;
+
+// ends 
+//     : end_of_stmt
+//     | ends end_of_stmt
+//     ;
+       
+
+// case_section
+//     : CASE case_clauses ends
+//       { 
+//             start_block();
+//       }
+//       opt_statement_list
+//       {
+//             //Block topmost = current_block;
+//             Block topmost = end_block();
+               
+//             while (topmost.Implicit)
+//                     topmost = topmost.Parent;
+                       
+//             // FIXME: This is a horrible hack which MUST go                 
+//             topmost.statements.Add (new Break (lexer.Location));
+//             $$ = new SwitchSection ((ArrayList) $2, topmost);
+//       }
+//     | CASE ELSE ends
+//         /* FIXME: we should somehow flag an error 
+//            (BC30321 'Case' cannot follow a 'Case Else' 
+//            in the same 'Select' statement.) 
+//            if Case Else is not the last of the Case clauses
+//         */
+//       { 
+//             start_block();
+//       }     
+//       opt_statement_list
+//       { 
+//             //Block topmost = current_block;
+//             Block topmost = end_block();
+
+//             while (topmost.Implicit)
+//                     topmost = topmost.Parent;
+                       
+//             // FIXME: This is a horrible hack which MUST go                 
+//             topmost.statements.Add (new Break (lexer.Location));
+               
+//             ArrayList a = new ArrayList();
+//             a.Add (new SwitchLabel (null, lexer.Location));                 
+//             $$ = new SwitchSection ((ArrayList) a, topmost);                
+//       }
+//     ;         
+       
+
+case_clauses
+       : case_clause
+         {
+               ArrayList labels = new ArrayList ();
+
+               labels.Add ($1);
+               $$ = labels;
+         }     
+       | case_clauses COMMA case_clause
+         {
+               ArrayList labels = (ArrayList) ($1);
+               labels.Add ($2);
+
+               $$ = labels;
+         }     
+       ;
+       
+case_clause
+       : opt_is comparison_operator expression
+       | expression
+         {
+               $$ = new SwitchLabel ((Expression) $1, lexer.Location);
+         }
+       ;
+       
+opt_is 
+       : /* empty */
+       | IS
+       ;
+
+comparison_operator
+       : OP_LT
+       | OP_GT
+       | OP_LE
+       | OP_NE
+       /*| OP_EQ */
+       ;
+
+opt_case
+       : /* empty */
+       | CASE
+       ;
+
+expression_statement
+       : statement_expression 
+         {
+                $$ = $1; 
+         }
+       ;
+
+
+statement_expression
+       : invocation_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
+       | object_creation_expression    { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
+       | assignment_expression         { $$ = new StatementExpression ((ExpressionStatement) $1, lexer.Location);  }
+       ;
+
+object_creation_expression
+       : NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS
+         {
+               $$ = new New ((Expression) $2, (ArrayList) $4, lexer.Location);
+         }
+       | NEW type
+         {
+               $$ = new New ((Expression) $2, new ArrayList(), lexer.Location);
+         }
+       ;
+       
+
+// array_creation_expression
+//     : object_creation_expression opt_rank_specifiers array_initializer
+//       {
+//             New n = (New) $1;
+//             ArrayList dims = new ArrayList();
+               
+//             if (n.Arguments != null) {
+//                     foreach (Argument a in n.Arguments) {
+//                             dims.Add (a.Expr);
+//                     }
+//             }
+                       
+//             Expression atype = n.RequestedType;
+
+//             if ($2 != null)
+//                     atype = DecomposeQI (atype.ToString () + VariableDeclaration.BuildRanks ((ArrayList)$2, true, lexer.Location), lexer.Location);
+
+//             ArrayList init = (ArrayList) $3;
+//             if (init.Count == 0)
+//                     init = null;
+       
+//             if (VariableDeclaration.IndexesSpecifiedInRank(dims)) {
+//                     VariableDeclaration.VBFixIndexList (ref dims);
+//                     $$ = new ArrayCreation (atype, dims, "", init, lexer.Location); 
+//             }
+//             else
+//             {
+//                     string rank = VariableDeclaration.BuildRank (dims);
+//                     $$ = new ArrayCreation (atype, rank, (ArrayList) $3, lexer.Location); 
+//             }
+//             //Console.WriteLine ("Creating a new array of type " + (atype.ToString()) + " with rank '" + dims + "'");
+//       }
+//     ;       
+
+new_expression
+       : object_creation_expression
+//     | array_creation_expression
+       ;
+
+declaration_statement
+       : local_variable_declaration 
+         {
+               if ($1 != null){
+                       DictionaryEntry de = (DictionaryEntry) $1;
+
+                       $$ = declare_local_variables ((Expression) de.Key, (ArrayList) de.Value, lexer.Location);
+               }
+         }
+       | local_constant_declaration 
+         {
+               if ($1 != null){
+                       DictionaryEntry de = (DictionaryEntry) $1;
+
+                       $$ = declare_local_constant ((Expression) de.Key, (ArrayList) de.Value);
+               }
+         }
+       ;        
+
+local_variable_declaration
+       : DIM variable_declarators
+         {
+               $$ = new DictionaryEntry (DecomposeQI("_local_vars_", lexer.Location), $2);             
+         }
+       ;
+
+       
+local_constant_declaration
+       : CONST constant_declarators
+         {
+               if ($2 != null)
+                       $$ = new DictionaryEntry (DecomposeQI("_local_consts_", lexer.Location), $2);
+               else
+                       $$ = null;
+         }
+       ;        
+
+constant_declarators
+       : constant_declarator 
+         {
+               ArrayList decl = new ArrayList ();
+               if ($1 != null) 
+                       decl.Add ($1);
+                       
+               $$ = decl;
+         }
+       | constant_declarators COMMA constant_declarator
+         {
+               ArrayList decls = (ArrayList) $1;
+               if ($3 != null)
+                       decls.Add ($3);
+
+               $$ = $1;
+         }
+       ;
+
+constant_declarator
+       : variable_name opt_type_decl opt_variable_initializer
+         {
+               VarName vname = (VarName) $1;
+               string varname = (string) vname.Name;
+               current_rank_specifiers = (ArrayList) vname.Rank;
+               object varinit = $3;
+               ArrayList a_dims = null;
+
+               if (varinit == null)
+                       Report.Error (
+                               30438, lexer.Location, "Constant should have a value"
+                               );
+
+               if (vname.Type != null && $2 != null)
+                       Report.Error (
+                               30302, lexer.Location, 
+                               "Type character cannot be used with explicit type declaration" );
+
+               Expression vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
+
+               if (current_rank_specifiers != null) 
+               {
+                       Report.Error (30424, lexer.Location, "Constant doesn't support array");
+                       $$ = null;
+               }
+               else
+                       $$ = new VariableDeclaration (varname, vartype, varinit, lexer.Location, null);
+         }
+       ;               
+
+variable_declarators
+       : variable_declarator 
+         {
+               ArrayList decl = new ArrayList ();
+               decl.AddRange ((ArrayList) $1);
+               $$ = decl;
+         }
+       | variable_declarators COMMA variable_declarator
+         {
+               ArrayList decls = (ArrayList) $1;
+               decls.AddRange ((ArrayList) $3);
+               $$ = $1;
+         }
+       ;
+
+variable_declarator
+       : variable_names opt_type_decl opt_variable_initializer
+         {
+           ArrayList names = (ArrayList) $1;
+               object varinit = $3;
+               ArrayList VarDeclarations = new ArrayList();
+               Expression vartype;
+               ArrayList a_dims = null;
+
+               if ((names.Count > 1) && (varinit != null)) 
+                       Report.Error (
+                               30671, lexer.Location, 
+                               "Multiple variables with single type can not have " +
+                               "a explicit initialization" );
+
+                               
+               foreach (VarName vname in names)
+               {
+                       string varname = (string) vname.Name;
+                       current_rank_specifiers = (ArrayList) vname.Rank;
+                       a_dims = null;
+                       varinit = $3;
+
+                       if(vname.Type != null && $2 != null)
+                               Report.Error (
+                                       30302, lexer.Location, 
+                                       "Type character cannot be used with explicit type declaration" );
+
+                       // Some checking is required for particularly weird declarations
+                       // like Dim a As Integer(,)
+                       if ($2 is Pair) {
+                               vartype = (Expression) ((Pair) $2).First;
+                               
+                               /*if ($3 != null && $3 is ArrayList)
+                                       Report.Error (205, "End of statement expected.");*/
+                                       
+                               ArrayList args = (ArrayList) ((Pair) $2).Second;
+                               if (current_rank_specifiers != null)
+                                       Report.Error (31087, lexer.Location,
+                                                "Array types specified in too many places");   
+                               
+                               if (VariableDeclaration.IndexesSpecifiedInRank (args))            
+                                       Report.Error (30638, "Array bounds cannot appear in type specifiers."); 
+                               
+                               current_rank_specifiers = new ArrayList ();
+                               current_rank_specifiers.Add (args);                             
+                       }
+                       else
+                               vartype = ($2 == null) ? ((vname.Type == null) ? TypeManager.system_object_expr : (Expression) vname.Type ) : (Expression) $2;
+
+                       // if the variable is an array with explicit bound
+                       // and having explicit initialization throw exception
+                       if (current_rank_specifiers != null && varinit != null) 
+                       {
+                               bool broken = false;
+                               foreach (ArrayList exprs in current_rank_specifiers)
+                               {
+                                       foreach (Expression expr in exprs)
+                                       {
+                                               if (!((Expression)expr is EmptyExpression ))
+                                               {
+                                                       Report.Error (
+                                                               30672, lexer.Location, 
+                                                               "Array declared with explicit bound " +
+                                                               " can not have explicit initialization");
+                                                       broken = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (broken)
+                                               break;
+                               }
+                       }
+                       
+                       /*
+                       Check for a declaration like Dim a(2) or Dim a(2,3)
+                       If this is the case, we must generate an ArrayCreationExpression
+                       and, in case, add the initializer after the array has been created.
+                       */
+//                     if (VariableDeclaration.IsArrayDecl (this)) {   
+//                             if (VariableDeclaration.IndexesSpecified(current_rank_specifiers)) {   
+//                                     a_dims = (ArrayList) current_rank_specifiers;
+//                                     VariableDeclaration.VBFixIndexLists (ref a_dims);
+//                                     varinit = VariableDeclaration.BuildArrayCreator(vartype, a_dims, (ArrayList) varinit, lexer.Location);
+//                             }
+//                             vartype = DecomposeQI (vartype.ToString() + VariableDeclaration.BuildRanks (current_rank_specifiers, false, lexer.Location), lexer.Location);
+//                     }
+
+                       if (vartype is New) {
+                               if (varinit != null) {
+                                       Report.Error (30205, lexer.Location, "End of statement expected");
+                                       $$ = null;
+                               }
+                               else
+                               {
+                                       varinit = vartype;
+                                       vartype = ((New)vartype).RequestedType;
+                               }
+                       }
+                       VarDeclarations.Add (new VariableDeclaration (varname, vartype, varinit, lexer.Location, null));
+           }// end of for
+           $$ = VarDeclarations;
+         } 
+       ;
+
+variable_names
+       : variable_name
+         {
+               ArrayList list = new ArrayList ();
+               list.Add ($1);
+               $$ = list;
+         }
+       | variable_names COMMA variable_name
+         {
+               ArrayList list = (ArrayList) $1;
+               list.Add ($3);
+               $$ = list;
+         }
+       ;
+       
+variable_name
+       : identifier opt_type_character opt_array_name_modifier 
+         {
+               $$ = new VarName ($1, $2, $3);
+         }
+       ;
+
+opt_type_spec
+       : /* empty */   
+         { 
+               $$ = null;              
+         }
+       | AS type       
+         { 
+               $$ = (Expression) $2;
+         }
+       ;
+               
+opt_type_with_ranks
+       : opt_type_spec 
+//     | AS type rank_specifiers 
+//       {
+// //          $$ = DecomposeQI ($2.ToString() + VariableDeclaration.BuildRanks ((ArrayList)$3, true, lexer.Location), lexer.Location);
+//       }
+       ;
+       
+opt_type_decl
+       : opt_type_with_ranks
+         {
+               $$ = $1;
+         }
+       | AS NEW type
+         {
+               New n = new New ((Expression)$3, null, lexer.Location);
+               $$ = (Expression) n;
+         }
+       | AS NEW type OPEN_PARENS opt_argument_list CLOSE_PARENS 
+         {
+               New n = new New ((Expression)$3, (ArrayList) $5, lexer.Location);
+               $$ = (Expression) n;
+         }
+       /*| AS NEW type OPEN_PARENS ADDRESSOF expression CLOSE_PARENS 
+         {
+           ArrayList args = new ArrayList();
+               Argument arg = new Argument ((Expression) $6, Argument.AType.Expression);
+               args.Add (arg);
+               
+               New n = new New ((Expression)$3, (ArrayList) args, lexer.Location);
+               $$ = (Expression) n;
+         }*/
+       ;
+               
+opt_array_name_modifier
+       : /* empty */                           { $$ = null; }
+//     | array_type_modifier                   { $$ = $1;   }
+       ;
+       
+// array_type_modifier
+//     : rank_specifiers               { $$ = $1; }
+//     ;
+       
+opt_variable_initializer
+       : /* empty */                   { $$ = null; }
+       | ASSIGN variable_initializer   { $$ = $2; }
+       ;
+               
+variable_initializer
+       : expression
+         {
+               $$ = $1;
+         }
+       | array_initializer
+         {
+               $$ = $1;
+         }
+       
+       ;       
+       
+array_initializer
+       : OPEN_BRACE CLOSE_BRACE
+         {
+               ArrayList list = new ArrayList ();
+               $$ = list;
+         }
+       | OPEN_BRACE variable_initializer_list CLOSE_BRACE
+         {
+               $$ = (ArrayList) $2;
+         }
+       ;
+
+variable_initializer_list
+       : variable_initializer
+         {
+               ArrayList list = new ArrayList ();
+               list.Add ($1);
+               $$ = list;
+         }
+       | variable_initializer_list COMMA variable_initializer
+         {
+               ArrayList list = (ArrayList) $1;
+               list.Add ($3);
+               $$ = list;
+         }
+       ;
+
+opt_rank_specifiers
+       : /* empty */
+         {
+                 // $$ = "";
+                 $$ = null;
+         }
+       | rank_specifiers
+         {
+                       $$ = $1;
+         }
+       ;      
+       
+rank_specifiers
+       : rank_specifier
+         {
+                 ArrayList rs = new ArrayList();
+                 rs.Add ($1);
+                 $$ = rs;
+         }
+       | rank_specifiers rank_specifier
+         {
+                 ArrayList rs = (ArrayList) $1;
+                 rs.Add ($2);
+                 $$ = rs;
+         }             
+        ;              
+       
+rank_specifier
+       : OPEN_PARENS opt_dim_specifiers CLOSE_PARENS
+         {
+               $$ = $2;
+         }
+       ;
+               
+opt_dim_specifiers
+       : /* empty */
+         {
+               ArrayList ds = new ArrayList();
+               ds.Add (new EmptyExpression());
+               $$ = ds;
+         }     
+       | expression
+         {
+               ArrayList ds = new ArrayList();
+               ds.Add ((Expression) $1);
+               $$ = ds;
+         }     
+       | opt_dim_specifiers COMMA expression
+         {
+               ArrayList ds = (ArrayList) $1;
+               ds.Add ((Expression) $3);
+               $$ = ds;                
+         }     
+       | opt_dim_specifiers COMMA 
+         {
+               ArrayList ds = (ArrayList) $1;
+               ds.Add (new EmptyExpression());
+               $$ = ds;                
+         }     
+       ;
+       
+// primary_expression
+//     : literal
+//       {
+//             //TODO
+//       }
+//     | parenthesized_expression
+//     | this_access
+//     | base_access
+//     | qualified_identifier
+//       {
+//             string name = (string) $1;
+//             $$ = DecomposeQI (name, lexer.Location);
+//       }
+//     | get_type_expression
+//     | member_access
+//     | invocation_expression
+//     //| element_access
+//     | new_expression
+//     | cast_expression
+//     ;
+
+primary_expression
+       : literal
+         {
+               //TODO
+         }
+       | parenthesized_expression
+       | this_access
+       | base_access
+       | qualified_identifier
+         {
+               $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
+         }
+       | get_type_expression
+       | member_access
+       | invocation_expression
+       //| element_access
+       | new_expression
+       | cast_expression
+       ;
+
+
+
+literal
+       : boolean_literal
+       | integer_literal
+       | real_literal
+//     | LITERAL_DATE                  { $$ = new DateLiteral ((DateTime)lexer.Value); }
+       | LITERAL_CHARACTER     { $$ = new CharLiteral ((char) lexer.Value); }
+       | LITERAL_STRING        { $$ = new StringLiteral ((string) lexer.Value); }
+       | NOTHING                               { $$ = NullLiteral.Null; }
+       ;
+
+real_literal
+       : LITERAL_SINGLE        { $$ = new FloatLiteral ((float) lexer.Value); }
+       | LITERAL_DOUBLE        { $$ = new DoubleLiteral ((double) lexer.Value); }
+       | LITERAL_DECIMAL       { $$ = new DecimalLiteral ((decimal) lexer.Value); }
+       ;
+
+integer_literal
+       : LITERAL_INTEGER       {
+               object v = lexer.Value;
+
+               if (v is int)
+                       $$ = new IntLiteral ((Int32)v); 
+//             else if (v is short)
+//                     $$ = new ShortLiteral ((Int16)v);
+               else if (v is long)
+                       $$ = new LongLiteral ((Int64)v);
+               else
+                       Console.WriteLine ("OOPS.  Unexpected result from scanner");
+                       
+         }
+       ;
+
+boolean_literal
+       : TRUE                  { $$ = new BoolLiteral (true); }
+       | FALSE                 { $$ = new BoolLiteral (false); }
+       ;
+
+parenthesized_expression
+       : OPEN_PARENS expression CLOSE_PARENS
+         { $$ = $2; }
+       ;
+
+member_access
+       : primary_expression DOT identifier
+         {
+               if ($1 != null) {
+                       string id_name = (string)$3;
+                       if (id_name.ToUpper() == "NEW")
+                               id_name = ".ctor";
+                       $$ = new MemberAccess ((Expression) $1, id_name, lexer.Location);
+               }
+               else
+               {
+//                     if (with_stack.Count > 0) {
+//                             Expression e = (Expression) with_stack.Peek();
+//                             $$ = new MemberAccess (e, (string) $3, lexer.Location);
+//                     }
+//                     else
+//                     {
+//                             // OOps
+//                     }
+               }
+         }
+/*     | primary_expression DOT NEW
+         {
+               $$ = new MemberAccess ((Expression) $1, (string) ".ctor", lexer.Location);
+         }       */
+       | predefined_type DOT identifier
+         {
+               if ($1 != null)
+                       $$ = new MemberAccess ((Expression) $1, (string) $3, lexer.Location);
+               else
+               {
+//                     if (with_stack.Count > 0) {
+//                             Expression e = (Expression) with_stack.Peek();
+//                             $$ = new MemberAccess (e, (string) $3, lexer.Location);
+//                     }
+//                     else
+//                     {
+//                             // OOps
+//                     }
+               }
+         }
+       ;
+       
+predefined_type
+       : builtin_types
+       ;
+
+invocation_expression
+       : primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
+         {
+               if ($1 == null) {
+                       Location l = lexer.Location;
+                       Report.Error (1, l, "Parse error");
+               }
+               $$ = new Invocation ((Expression) $1, (ArrayList) $3, lexer.Location);
+         }
+       | CALL primary_expression OPEN_PARENS opt_argument_list CLOSE_PARENS
+         {
+               if ($2 == null) {
+                       Location l = lexer.Location;
+                       Report.Error (1, l, "THIS IS CRAZY");
+               }
+               $$ = new Invocation ((Expression) $2, (ArrayList) $3, lexer.Location);
+//             Console.WriteLine ("Invocation: {0} with {1} arguments", $2, ($3 != null) ? ((ArrayList) $3).Count : 0);
+         }
+       ;
+       
+base_access
+       : MYBASE DOT IDENTIFIER
+         {
+               string id_name = (string) $3;
+               if (id_name.ToUpper() == "NEW")
+                       id_name = "New";
+               $$ = new BaseAccess (id_name, lexer.Location);
+         }
+/*     | MYBASE DOT NEW
+         {
+               $$ = new BaseAccess ("New", lexer.Location);
+         }*/
+       ;       
+
+opt_argument_list
+       : argument_list
+         { 
+               /*
+                  The 'argument' rule returns an 'empty' argument
+                  of type NoArg (used for default arguments in invocations)
+                  if no arguments are actually passed.
+
+                  If there is only one argument and it is o type NoArg,
+                  we return a null (empty) list
+               */
+               ArrayList args = (ArrayList) $1;
+               if (args.Count == 1 &&
+                   ((Argument)args[0]).ArgType == Argument.AType.NoArg)
+                       $$ = null;
+               else
+                       $$ = $1;
+         }
+       ;
+
+argument_list
+       : argument
+         {
+               ArrayList list = new ArrayList ();
+               list.Add ($1);
+               $$ = list;
+         }
+       | argument_list COMMA argument
+         {
+               ArrayList list = (ArrayList) $1;
+               list.Add ($3);
+               $$ = list;
+         }
+       ;
+
+argument
+       : expression
+         {
+               $$ = new Argument ((Expression) $1, Argument.AType.Expression);
+         }
+       | BYREF variable_reference
+         {
+               $$ = new Argument ((Expression) $2, Argument.AType.Ref);
+         }
+       | /* empty */
+         {
+               $$ = new Argument (new EmptyExpression (), Argument.AType.NoArg);
+         }
+       | ADDRESSOF expression
+         {
+               $$ = new Argument ((Expression) $2, Argument.AType.AddressOf);
+         }
+       ;
+
+variable_reference
+       : expression {/* note ("section 5.4"); */  $$ = $1;  }
+       ;
+
+               
+expression
+       : conditional_xor_expression { $$ = $1; }
+       /*| assignment_expression*/
+       ;
+
+opt_expression
+       : /* empty */
+       | expression
+       ;
+               
+this_access
+       : ME
+         {
+               $$ = new This (current_block, lexer.Location);
+         }
+       | MYCLASS
+         {
+               // FIXME: This is actually somewhat different from Me
+               // because it is for accessing static (classifier) methods/properties/fields
+               $$ = new This (current_block, lexer.Location);
+         }
+       ;
+
+cast_expression
+        : DIRECTCAST OPEN_PARENS expression COMMA type CLOSE_PARENS
+         {
+               // TODO
+         } 
+       | CTYPE OPEN_PARENS expression COMMA type CLOSE_PARENS
+         {
+                 $$ = new Cast ((Expression) $5, (Expression) $3, lexer.Location);
+         }     
+        | cast_operator OPEN_PARENS expression CLOSE_PARENS
+         {
+                 $$ = new Cast ((Expression) $1, (Expression) $3, lexer.Location);
+         }     
+       ;
+       
+cast_operator
+       : CBOOL         { $$ = TypeManager.system_boolean_expr;         }
+       | CBYTE         { $$ = TypeManager.system_byte_expr;            }
+       | CCHAR         { $$ = TypeManager.system_char_expr;            }
+//     | CDATE         { $$ = TypeManager.system_date_expr;            }
+       | CDBL          { $$ = TypeManager.system_double_expr;          }
+       | CDEC          { $$ = TypeManager.system_decimal_expr;         }
+       | CINT          { $$ = TypeManager.system_int32_expr;           }
+       | CLNG          { $$ = TypeManager.system_int64_expr;           }
+       | COBJ          { $$ = TypeManager.system_object_expr;          }
+       | CSHORT        { $$ = TypeManager.system_int16_expr;           }
+       | CSNG          { $$ = TypeManager.system_single_expr;          }
+       | CSTR          { $$ = TypeManager.system_string_expr;  }
+       ;
+
+get_type_expression
+       : GETTYPE OPEN_PARENS type CLOSE_PARENS
+         {
+               $$ = new TypeOf ((Expression) $3, lexer.Location);
+         }
+       ;
+       
+exponentiation_expression
+       : primary_expression
+       | exponentiation_expression OP_EXP primary_expression
+         {
+               //TODO
+         }                             
+       ;
+       
+prefixed_unary_expression
+       : exponentiation_expression
+       | PLUS prefixed_unary_expression
+         {
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Unary (Unary.Operator.UnaryPlus, (Expression) $2, lexer.Location);
+         }
+       | MINUS prefixed_unary_expression
+         {
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Unary (Unary.Operator.UnaryNegation, (Expression) $2, lexer.Location);
+         }
+       ;
+
+multiplicative_expression
+       : prefixed_unary_expression
+       | multiplicative_expression STAR prefixed_unary_expression
+         {
+               $$ = new Binary (Binary.Operator.Multiply,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | multiplicative_expression DIV prefixed_unary_expression
+         {
+               $$ = new Binary (Binary.Operator.Division,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       ;
+
+integer_division_expression
+       : multiplicative_expression
+       | integer_division_expression OP_IDIV multiplicative_expression
+          {
+               //FIXME: Is this right ?
+               $$ = new Binary (Binary.Operator.Division,
+                          (Expression) $1, (Expression) $3, lexer.Location);
+          }
+       ;
+
+mod_expression
+       : integer_division_expression
+       | mod_expression MOD integer_division_expression
+         {
+             $$ = new Binary (Binary.Operator.Modulus,
+                              (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       ;
+       
+additive_expression
+       : mod_expression
+       | additive_expression PLUS mod_expression
+         {
+               $$ = new Binary (Binary.Operator.Addition,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | additive_expression MINUS mod_expression
+         {
+               $$ = new Binary (Binary.Operator.Subtraction,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       ;
+
+concat_expression
+       : additive_expression
+       | concat_expression OP_CONCAT additive_expression
+          {
+             // FIXME: This should only work for String expressions
+             // We probably need to use something from the runtime
+             $$ = new Binary (Binary.Operator.Addition,
+                              (Expression) $1, (Expression) $3, lexer.Location);
+         }     
+       ;
+
+shift_expression
+       : concat_expression
+       | shift_expression OP_SHIFT_LEFT concat_expression
+         {
+               // TODO
+         }
+       | shift_expression OP_SHIFT_RIGHT concat_expression
+         {
+               //TODO
+         }
+       ;
+
+relational_expression
+       : shift_expression
+       | relational_expression ASSIGN shift_expression
+         {
+               $$ = new Binary (Binary.Operator.Equality,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | relational_expression OP_NE shift_expression
+         {
+               $$ = new Binary (Binary.Operator.Inequality, 
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }       
+       | relational_expression OP_LT shift_expression
+         {
+               $$ = new Binary (Binary.Operator.LessThan,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | relational_expression OP_GT shift_expression
+         {
+               $$ = new Binary (Binary.Operator.GreaterThan,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | relational_expression OP_LE shift_expression
+         {
+               $$ = new Binary (Binary.Operator.LessThanOrEqual,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | relational_expression OP_GE shift_expression
+         {
+               $$ = new Binary (Binary.Operator.GreaterThanOrEqual,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | relational_expression IS shift_expression
+         {
+               //FIXME: Should be a different op for reference equality but allows tests to use Is
+               $$ = new Binary (Binary.Operator.Equality,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | TYPEOF shift_expression IS type
+         {
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Is ((Expression) $2, (Expression) $4, lexer.Location);
+         }
+       ;
+
+negation_expression
+       : relational_expression
+       | NOT negation_expression 
+         {
+               //FIXME: Is this rule correctly defined ?
+               $$ = new Unary (Unary.Operator.LogicalNot, (Expression) $2, lexer.Location);
+         }
+       ;
+       
+conditional_and_expression
+       : negation_expression
+       | conditional_and_expression AND negation_expression
+         {
+               $$ = new Binary (Binary.Operator.LogicalAnd,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | conditional_and_expression ANDALSO negation_expression
+         {     // FIXME: this is likely to be broken
+               $$ = new Binary (Binary.Operator.LogicalAnd,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       ;
+
+conditional_or_expression
+       : conditional_and_expression
+       | conditional_or_expression OR conditional_and_expression
+         {
+               $$ = new Binary (Binary.Operator.LogicalOr,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | conditional_or_expression ORELSE conditional_and_expression
+         {     // FIXME: this is likely to be broken
+               $$ = new Binary (Binary.Operator.LogicalOr,
+                                (Expression) $1, (Expression) $3, lexer.Location);
+         }
+       ;
+
+conditional_xor_expression
+       : conditional_or_expression
+       | conditional_xor_expression XOR conditional_or_expression
+       {
+             $$ = new Binary (Binary.Operator.ExclusiveOr,
+                              (Expression) $1, (Expression) $3, lexer.Location);
+       }
+       ;
+
+assignment_expression
+       : prefixed_unary_expression ASSIGN expression
+         { 
+               $$ = new Assign ((Expression) $1, (Expression) $3, lexer.Location);
+         }
+       | prefixed_unary_expression STAR ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.Multiply, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression DIV ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.Division, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression PLUS ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression MINUS ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.Subtraction, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression OP_SHIFT_LEFT ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.LeftShift, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression OP_SHIFT_RIGHT ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               $$ = new CompoundAssign (
+                       Binary.Operator.RightShift, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression OP_CONCAT ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               // FIXME should be strings only
+               $$ = new CompoundAssign (
+                       Binary.Operator.Addition, (Expression) $1, (Expression) $4, l);
+         }
+       | prefixed_unary_expression OP_EXP ASSIGN expression
+         {
+               Location l = lexer.Location;
+
+               /* TODO: $$ = new CompoundAssign (
+                       Binary.Operator.ExclusiveOr, (Expression) $1, (Expression) $4, l); */
+         }
+       | prefixed_unary_expression ASSIGN ADDRESSOF expression
+         { 
+//             ArrayList args = new ArrayList();
+//             Argument arg = new Argument ((Expression) $4, Argument.AType.Expression);
+//             args.Add (arg);
+               
+//             New n = new New ((Expression) $1, (ArrayList) args, lexer.Location);
+//             n.isDelegate = true;
+               $$ = new Assign ((Expression) $1, (Expression) $4, lexer.Location);
+         }
+       ;
+
+constant_expression
+       : expression
+       ;
+
+boolean_expression
+       : expression
+       ;
+
+type
+       : namespace_or_type_name 
+         {     
+               $$ = ((MemberName) $1).GetTypeExpression (lexer.Location);
+         }
+       | builtin_types 
+       //| array_type 
+       ;
+
+type_list
+       : type
+         {
+               ArrayList types = new ArrayList ();
+
+               types.Add ($1);
+               $$ = types;
+         }
+       | type_list COMMA type
+         {
+               ArrayList types = (ArrayList) $1;
+
+               types.Add ($3);
+               $$ = types;
+         }
+       ;
+
+namespace_or_type_name
+       : qualified_identifier
+       ;
+
+builtin_types
+       : OBJECT        { $$ = TypeManager.system_object_expr; }
+       | primitive_type
+       ;
+
+primitive_type
+       : numeric_type
+       | BOOLEAN       { $$ = TypeManager.system_boolean_expr; }
+//     | DATE          { $$ = TypeManager.system_date_expr; }
+       | CHAR          { $$ = TypeManager.system_char_expr; }
+       | STRING        { $$ = TypeManager.system_string_expr; }
+       ;
+       
+
+numeric_type
+       : integral_type
+       | floating_point_type
+       | DECIMAL       { $$ = TypeManager.system_decimal_expr; }
+       ;
+
+integral_type
+       :
+       | BYTE          { $$ = TypeManager.system_byte_expr; }
+       | SHORT         { $$ = TypeManager.system_int16_expr; }
+       | INTEGER       { $$ = TypeManager.system_int32_expr; }
+       | LONG          { $$ = TypeManager.system_int64_expr; }
+       ;
+       
+floating_point_type
+       : SINGLE        { $$ = TypeManager.system_single_expr; }
+       | DOUBLE        { $$ = TypeManager.system_double_expr; }
+       ;
+
+pp_directive
+       : HASH IDENTIFIER OPEN_PARENS LITERAL_STRING COMMA LITERAL_INTEGER CLOSE_PARENS EOL
+         { 
+//             if(tokenizerController.IsAcceptingTokens)
+//             {
+//                     if(in_external_source) 
+//                             Report.Error (30580, lexer.Location, "#ExternalSource directives may not be nested");
+//                     else {
+//                             in_external_source = true;
+                       
+//                             lexer.EffectiveSource = (string) $4;
+//                             lexer.EffectiveLine = (int) $6;
+//                     }
+//             }
+         }
+       | HASH IDENTIFIER LITERAL_STRING EOL
+         {
+               if(tokenizerController.IsAcceptingTokens) 
+               {
+                       string id = ($2 as string);
+               
+                       if(!($2 as string).ToLower().Equals("region"))
+                               Report.Error (30205, lexer.Location, "Invalid Pre-processor directive");
+                       else
+                       {
+                               ++in_marked_region;
+                       }
+               }
+         }
+       | HASH END IDENTIFIER EOL
+         {
+               if(tokenizerController.IsAcceptingTokens)
+               {
+//                     if( ($3 as string).ToLower().Equals("externalsource")) {
+//                             if(!in_external_source)
+//                                     Report.Error (30578, lexer.Location, "'#End ExternalSource' must be preceded by a matching '#ExternalSource'");
+//                             else {
+//                                     in_external_source = false;
+//                                     lexer.EffectiveSource = lexer.Source;
+//                                     lexer.EffectiveLine = lexer.Line;
+//                             }
+//                     }
+                       /* else */if(($3 as string).ToLower().Equals("region")) {
+                               if(in_marked_region > 0)
+                                       --in_marked_region;
+                               else
+                                       Report.Error (30205, lexer.Location, "'#End Region' must be preceded  by a matching '#Region'");
+                       }
+                       else {
+                               Report.Error (29999, lexer.Location, "Unrecognized Pre-Processor statement");
+                       }       
+               }
+         }
+       | HASH CONST IDENTIFIER ASSIGN boolean_literal EOL
+         {
+               if(tokenizerController.IsAcceptingTokens)
+               {
+                       //TODO;
+               }
+         }
+       | HASH IF 
+         {
+               IfElseStateMachine.Token tok = IfElseStateMachine.Token.IF;
+
+               try {
+                       ifElseStateMachine.HandleToken(tok);
+               }
+               catch(ApplicationException) {
+                       throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+               }
+         }
+          boolean_literal opt_then  EOL 
+         {
+               HandleConditionalDirective(IfElseStateMachine.Token.IF, (BoolLiteral)$4);
+         }
+       | HASH ELSEIF 
+         {
+                     IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSEIF;
+                     try {
+                             ifElseStateMachine.HandleToken(tok);
+                     }
+                     catch(ApplicationException) {
+                             throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                     }
+         }
+          boolean_literal opt_then  EOL 
+         { 
+                 HandleConditionalDirective(IfElseStateMachine.Token.ELSEIF, (BoolLiteral)$4);
+         }
+       | HASH ELSE  
+         {
+                   IfElseStateMachine.Token tok = IfElseStateMachine.Token.ELSE;
+                   try {
+                           ifElseStateMachine.HandleToken(tok);
+                   }
+                   catch(ApplicationException) {
+                           throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                   }
+         }
+         EOL 
+         { 
+               HandleConditionalDirective(IfElseStateMachine.Token.ELSE, new BoolLiteral(true));
+         }
+       | HASH END IF  
+         {
+                 IfElseStateMachine.Token tok = IfElseStateMachine.Token.ENDIF;
+                 try {
+                         ifElseStateMachine.HandleToken(tok);
+                 }
+                 catch(ApplicationException) {
+                         throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+                 }
+         }
+         EOL 
+         { 
+               HandleConditionalDirective(IfElseStateMachine.Token.ENDIF, new BoolLiteral(false));
+         }
+       | HASH error EOL          
+       {
+               if(tokenizerController.IsAcceptingTokens)
+                       Report.Error(2999, lexer.Location, "Unrecognized Pre-Processor statement");
+               else
+                       Report.Warning (9999, lexer.Location,   "Unrecognized Pre-Processor statement");
+       }
+         
+       ;               
+
+%%
+
+
+Tokenizer lexer;
+
+public Tokenizer Lexer {
+       get {
+               return lexer;
+       }
+}                 
+
+public static Expression DecomposeQI (string name, Location loc)
+{
+       Expression o;
+
+       if (name.IndexOf ('.') == -1){
+               return new SimpleName (name, loc);
+       } else {
+               int pos = name.LastIndexOf (".");
+               string left = name.Substring (0, pos);
+               string right = name.Substring (pos + 1);
+
+               o = DecomposeQI (left, loc);
+
+               return new MemberAccess (o, right, loc);
+       }
+}
+
+Block declare_local_variables (Expression dummy_type, ArrayList variable_declarators, Location loc)
+{
+       Block implicit_block;
+       ArrayList inits = null;
+
+       //
+       // We use the `Used' property to check whether statements
+       // have been added to the current block.  If so, we need
+       // to create another block to contain the new declaration
+       // otherwise, as an optimization, we use the same block to
+       // add the declaration.
+       //
+       // FIXME: A further optimization is to check if the statements
+       // that were added were added as part of the initialization
+       // below.  In which case, no other statements have been executed
+       // and we might be able to reduce the number of blocks for
+       // situations like this:
+       //
+       // int j = 1;  int k = j + 1;
+       //
+       
+       VariableDeclaration.FixupTypes (variable_declarators);
+       // FIXME: Should VariableDeclaration.FixupArrayTypes be called here
+
+       if (current_block.Used)
+               implicit_block = new Block (current_block, Block.Flags.Implicit, loc, Location.Null);
+       else
+               implicit_block = current_block;
+
+
+       foreach (VariableDeclaration decl in variable_declarators){
+               Expression type = decl.type;
+               if (implicit_block.AddVariable (type, decl.identifier, current_local_parameters, decl.Location) != null) {
+                       if (decl.expression_or_array_initializer != null){
+                               if (inits == null)
+                                       inits = new ArrayList ();
+                               inits.Add (decl);
+                       }
+               }
+       }
+
+       if (inits == null)
+               return implicit_block;
+
+       foreach (VariableDeclaration decl in inits){
+               Assign assign;
+               Expression expr;
+               Expression type = decl.type;
+               
+               if ((decl.expression_or_array_initializer is Expression) || 
+                   (decl.expression_or_array_initializer is New)) {
+                       expr = (Expression) decl.expression_or_array_initializer;
+               } else {
+                       ArrayList init = (ArrayList) decl.expression_or_array_initializer;
+                       
+                       expr = new ArrayCreation (type, "", init, decl.Location);
+               }
+
+               LocalVariableReference var;
+               var = new LocalVariableReference (implicit_block, decl.identifier, loc);
+
+               assign = new Assign (var, expr, decl.Location);
+
+               implicit_block.AddStatement (new StatementExpression (assign, lexer.Location));
+       }
+       
+       return implicit_block;
+}
+
+Block declare_local_constant (Expression dummy_type, ArrayList variable_declarators)
+{
+       Block implicit_block;
+       VariableDeclaration.FixupTypes (variable_declarators);
+
+       if (current_block.Used)
+               implicit_block = new Block (current_block, Block.Flags.Implicit);
+       else
+               implicit_block = current_block;
+
+       foreach (VariableDeclaration decl in variable_declarators){
+               Expression type = decl.type;
+               implicit_block.AddConstant (type, decl.identifier, (Expression) decl.expression_or_array_initializer,
+                                         current_local_parameters, decl.Location);
+       }
+       
+       return implicit_block;
+}
+
+
+
+struct VarName {
+                public object Name;
+                public object Type;
+               public object Rank;
+                                                                                
+                public VarName (object n, object t, object r)
+                {
+                        Name = n;
+                        Type = t;
+                       Rank = r;
+                }
+        }
+
+
+// <summary>
+//   A class used to pass around variable declarations and constants
+// </summary>
+public class VariableDeclaration {
+       public string identifier;
+       public object expression_or_array_initializer;
+       public Location Location;
+       public Attributes OptAttributes;
+       public string DocComment;
+       public Expression type;
+       public ArrayList dims;
+               
+       public VariableDeclaration (string id, Expression t, object eoai, Location l, Attributes opt_attrs)
+       {
+               this.identifier = id;
+               this.expression_or_array_initializer = eoai;
+               this.Location = l;
+               this.OptAttributes = opt_attrs;
+               this.type = t;
+               this.dims = null;
+       }       
+
+       public VariableDeclaration (string id, object eoai, Location l) : this (id, eoai, l, null)
+       {
+       }
+       
+       public VariableDeclaration (string id, Expression t, Location l) : this (id, t, null, l, null)
+       {
+       }       
+       
+       public VariableDeclaration (string id, object eoai, Location l, Attributes opt_attrs) : this 
+                                       (id, TypeManager.system_object_expr, eoai, l, opt_attrs)
+       {
+       }       
+       
+       public static ArrayCreation BuildArrayCreator (Expression vartype, ArrayList a_dims, ArrayList varinit, Location l)
+       {       
+               // FIXME : This is broken: only the first rank is parsed
+               return new ArrayCreation (vartype, (ArrayList) a_dims[0], "", varinit, l);
+       }
+       
+       public static void FixupTypes (ArrayList vars)
+       {
+               int varcount =  vars.Count;
+               VariableDeclaration last_var = (VariableDeclaration) vars[varcount - 1];
+                       
+               if (last_var.type == null)
+                       last_var.type = TypeManager.system_object_expr;
+                       
+               Expression cur_type = last_var.type;
+               int n = varcount - 1;
+               
+               while (n >= 0) {
+                       VariableDeclaration var = (VariableDeclaration) vars[n--];
+                       if (var.type == null)
+                               var.type = cur_type;
+                       else
+                               cur_type = var.type;
+               }
+       }
+       
+       public static bool IndexesSpecifiedInRank (ArrayList IndexList)
+       {
+               bool res = false;
+               
+               if (IndexList != null) {
+                       foreach (Expression e in IndexList)
+                               if (!(e is EmptyExpression)) {
+                                       res = true;
+                                       break;
+                               }       
+               }
+               return (res);
+       }       
+       
+       
+       public static bool IndexesSpecified (ArrayList ranks)
+       {
+               bool res = false;
+               
+               if (ranks != null) {
+                       foreach (ArrayList IndexList in ranks) {
+                               if (IndexesSpecifiedInRank (IndexList)) {
+                                       res = true;
+                                       break;
+                               }       
+                       }       
+               }
+               return (res);
+       }
+       
+       public static string StripDims (string varname, ref string d)
+       {
+               string res = varname;
+               string dres = "";
+               
+               if (varname.IndexOf("[") >= 0) {
+                       dres = varname.Substring(varname.IndexOf("["), (varname.LastIndexOf("]") - varname.IndexOf("["))+1);
+                       res = varname.Substring(0, varname.IndexOf("["));
+               }
+               d = dres;
+               return (res);
+       }       
+       
+       public static string StripDims (string varname)
+       {
+               string dres = "";
+               
+               return (StripDims(varname, ref dres));
+       }       
+       
+       public static string StripIndexesFromDims (string dims)
+       {
+               StringBuilder sb = new StringBuilder();
+
+               foreach (char c in dims) 
+                       if (c == ',' || c == ']' || c == '[')
+                               sb.Append (c);
+                               
+               return sb.ToString();                           
+       }
+       
+       public static string BuildRank (ArrayList rank)
+       {
+               bool allEmpty;
+               return BuildRank(rank, out allEmpty);
+       }
+            
+       public static string BuildRank (ArrayList rank, out bool allEmpty)
+       {
+               string res = "";
+
+               res += "[";
+               allEmpty = true;
+               bool first = true;
+               foreach (object e in rank) {
+                       if (!(e is EmptyExpression))
+                               allEmpty = false;
+                       if (!first)
+                               res += ",";
+                       first = false;
+               }
+                       
+               res += "]";
+               return res;
+       }
+               
+       public static string BuildRanks (ArrayList rank_specifiers, bool mustBeEmpty, Location loc)
+       {
+               string res = "";
+
+               bool allEmpty = true;
+               foreach (ArrayList rank in rank_specifiers) {
+                       bool tmp;
+                       res = BuildRank (rank, out tmp) + res;
+                       if (!tmp)
+                               allEmpty = false;
+               }
+               if (!allEmpty && mustBeEmpty)
+                       Report.Error (30638, loc, "Array bounds cannot appear in type specifiers.");    
+
+               return res;
+       }       
+       
+       public static void VBFixIndexList (ref ArrayList IndexList)
+       {
+               if (IndexList != null) {
+                       for (int x = 0; x < IndexList.Count; x++) {
+                               Expression e = (Expression) IndexList[x];
+                               if (!(e is EmptyExpression)) {
+                                       IndexList[x] = new Binary (Binary.Operator.Addition, e, new IntLiteral(1), Location.Null);
+                               }
+                       }
+               }
+       }               
+       
+//     public static bool IsArrayDecl (Parser t)
+//     {
+//             // return (varname.IndexOf("[") >= 0);
+//             return (t.current_rank_specifiers != null);
+//     }                       
+       
+       public static void VBFixIndexLists (ref ArrayList ranks)
+       {       
+               if (ranks != null) {
+                       for (int x = 0; x < ranks.Count; x++) {
+                               ArrayList IndexList = (ArrayList) ranks[x];
+                               VBFixIndexList (ref IndexList);
+                       }       
+               }       
+       }
+               
+       public static void FixupArrayTypes (ArrayList vars)
+       {
+               int varcount =  vars.Count;
+               string dims;
+               
+               foreach (VariableDeclaration var in vars) {
+                       if (var.identifier.EndsWith(",")) {
+                               dims = "[" + var.identifier.Substring(var.identifier.IndexOf (","), 
+                                                               var.identifier.LastIndexOf(",")) + "]";
+                               var.identifier = var.identifier.Substring (0, var.identifier.IndexOf (","));
+                               var.type = new ComposedCast (var.type, (string) dims, var.Location);
+                       }
+               }
+       }                               
+}
+
+
+// public Property BuildSimpleProperty (Expression p_type, string name, 
+//                                     Field p_fld, int mod_flags,
+//                                     Attributes attrs, Location loc) 
+// {
+//     Property p;
+//     Block get_block, set_block;
+//     Accessor acc_set, acc_get;
+//     StatementExpression a_set;
+//     Statement a_get;
+//     Parameter [] args;
+       
+//     // Build SET Block
+//     Parameter implicit_value_parameter = new Parameter (p_type, "value", Parameter.Modifier.NONE, null);    
+//     args  = new Parameter [1];
+//     args [0] = implicit_value_parameter;
+               
+//     Parameters set_params = new Parameters (args, null, loc);
+//     a_set = new StatementExpression ((ExpressionStatement) new Assign ((Expression) DecomposeQI(p_fld.Name, loc), 
+//                         (Expression) new SimpleName("value", loc), loc), loc);
+                           
+//     set_block = new Block (current_block, set_params, loc, Location.Null);
+//     set_block.AddStatement ((Statement) a_set);                                         
+//     acc_set = new Accessor (set_block, attrs);
+       
+//     // Build GET Block
+//     a_get = (Statement) new Return ((Expression) DecomposeQI(p_fld.Name, loc), loc);
+//     get_block = new Block (current_block, null, loc, Location.Null);
+//     get_block.AddStatement ((Statement) a_get);                                         
+//     acc_get = new Accessor (get_block, attrs);
+               
+//     p = new Property (p_type, name, mod_flags, (Accessor) acc_get, (Accessor) acc_set, attrs, loc);
+       
+//     return (p);
+// }
+       
+void start_block () 
+{
+         if (current_block == null){
+                 current_block = new ToplevelBlock ((ToplevelBlock) top_current_block, 
+                                            current_local_parameters, lexer.Location);
+                 top_current_block = current_block;
+         } else {
+                 current_block = new Block (current_block, current_local_parameters,
+                                                lexer.Location, Location.Null);
+         }
+} 
+
+
+Block end_block ()
+{ 
+       Block res;
+
+       while (current_block.Implicit)
+               current_block = current_block.Parent;
+       res = current_block;
+       current_block.SetEndLocation (lexer.Location);
+       current_block = current_block.Parent;
+       if (current_block == null)
+               top_current_block = null;
+
+       return res;
+}
+
+// private void AddHandler (Expression evt_definition, Expression handler_exp)
+// {
+//     AddHandler (current_block, evt_definition, handler_exp);
+// }
+
+void CheckAttributeTarget (string a)
+{
+       switch (a) {
+
+       case "assembly" : case "field" : case "method" : case "param" : case "property" : case "type" :
+               return;
+               
+       default :
+               Location l = lexer.Location;
+               Report.Error (658, l, "`" + a + "' is an invalid attribute target");
+               break;
+       }
+}
+
+// private void AddHandler (Block b, Expression evt_id, Expression handles_exp)
+// {
+//     Expression evt_target;
+//     Location loc = lexer.Location;
+       
+//     Statement addhnd = (Statement) new AddHandler (evt_id, 
+//                                                                                                     handles_exp, 
+//                                                                                                     loc);                                                                                                   
+                                                                                                       
+//     b.AddStatement (addhnd);
+// }
+
+// private void RaiseEvent (string evt_name, ArrayList args)
+// {
+//     Location loc = lexer.Location;
+       
+//     Invocation evt_call = new Invocation (DecomposeQI(evt_name, loc), args, lexer.Location);
+//     Statement s = (Statement)(new StatementExpression ((ExpressionStatement) evt_call, loc)); 
+//     current_block.AddStatement (s); 
+// }
+
+// private void RemoveHandler (Block b, Expression evt_definition, Expression handler_exp)
+// {
+//     Expression evt_target;
+//     Location loc = lexer.Location;
+       
+//     Statement rmhnd = (Statement) new RemoveHandler (evt_definition, 
+//                                                                                                     handler_exp, 
+//                                                                                                     loc);
+//     b.AddStatement (rmhnd);
+// }
+
+// <summary>
+//  This method is used to get at the complete string representation of
+//  a fully-qualified type name, hiding inside a MemberAccess ;-)
+//  This is necessary because local_variable_type admits primary_expression
+//  as the type of the variable. So we do some extra checking
+// </summary>
+string GetQualifiedIdentifier (Expression expr)
+{
+       if (expr is SimpleName)
+               return ((SimpleName)expr).Name;
+       else if (expr is MemberAccess)
+               return GetQualifiedIdentifier (((MemberAccess)expr).Expr) + "." + ((MemberAccess) expr).Identifier;
+       else 
+               throw new Exception ("Expr has to be either SimpleName or MemberAccess! (" + expr + ")");
+       
+}
+
+// private void RemoveHandler (Expression evt_definition, Expression handler_exp)
+// {
+//     RemoveHandler (current_block, evt_definition, handler_exp);
+// }
+
+// FIXME: This needs to be fixed for This and Base access because the way the name of the
+// mbas' constructor is changed from "New" to current_container.Basename
+
+private ConstructorInitializer CheckConstructorInitializer (ref ArrayList s)
+{
+       ConstructorInitializer ci = null;
+       
+       if (s.Count > 0) {
+               if (s[0] is StatementExpression && ((StatementExpression) s[0]).expr is Invocation) {
+                       Invocation i = (Invocation) ((StatementExpression) s[0]).expr;
+                       
+                       if (i.expr is BaseAccess) {
+                               BaseAccess ba = (BaseAccess) i.expr;
+                               if (ba.member == "New" || ba.member == ".ctor") {
+                                       ci = new ConstructorBaseInitializer (i.Arguments, current_local_parameters, lexer.Location);
+                                       s.RemoveAt(0);
+                               }
+                       }
+                       if (i.expr.ToString() == "Mono.MonoBASIC.This..ctor") {
+                               ci = new ConstructorThisInitializer (i.Arguments, current_local_parameters, lexer.Location); 
+                               s.RemoveAt(0);
+                       }
+               }
+       }
+       return ci;
+}
+
+void Error_ExpectingTypeName (Location l, Expression expr)
+{
+       if (expr is Invocation){
+               Report.Error (1002, l, "; expected");
+       } else {
+               Report.Error (-1, l, "Invalid Type definition");
+       }
+}
+
+static bool AlwaysAccept (MemberInfo m, object filterCriteria) {
+       return true;
+}
+
+private void ReportError9998()
+{
+       Report.Error (29998, lexer.Location, "This construct is only available in MonoBASIC extended syntax.");
+}
+
+public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList defines)
+{
+       current_namespace = new NamespaceEntry (null, file, null, Location.Null);
+       this.name = file.Name;
+       this.file = file;
+       current_container = RootContext.Tree.Types;
+       current_container.NamespaceEntry = current_namespace;
+       oob_stack = new Stack ();
+       switch_stack = new Stack ();
+
+       lexer = new Tokenizer (reader, file, defines);
+
+       ifElseStateMachine = new IfElseStateMachine();
+       tokenizerController = new TokenizerController(lexer);
+}
+
+public void parse ()
+{
+       try {
+               if (yacc_verbose_flag > 1)
+                       yyparse (lexer, new yydebug.yyDebugSimple ());
+               else
+                       yyparse (lexer);
+               Tokenizer tokenizer = lexer as Tokenizer;
+               tokenizer.cleanup ();           
+       } catch (Exception e){
+               // 
+               // Removed for production use, use parser verbose to get the output.
+               //
+               // Console.WriteLine (e);
+               Report.Error (-25, lexer.Location, "Parsing error");
+               if (yacc_verbose_flag > 0)
+                       Console.WriteLine (e);
+       }
+}
+
+
+// protected override int parse ()
+// {
+//     RootContext.InitializeImports(ImportsList);
+//     current_namespace = new Namespace (null, RootContext.RootNamespace);
+//     current_container = RootContext.Tree.Types;
+//     current_container.Namespace = current_namespace;
+//     oob_stack = new Stack ();
+//     switch_stack = new Stack ();
+//     expr_stack = new Stack ();      
+//     tmp_blocks = new Stack(); 
+//     with_stack = new Stack();
+//     statement_stack = new Stack();  
+
+//     allow_global_attribs = true;
+//     expecting_global_attribs = false;
+//     expecting_local_attribs = false;
+//     local_attrib_section_added = false;
+
+//     UseExtendedSyntax = name.EndsWith(".mbs");
+//     OptionExplicit = InitialOptionExplicit || UseExtendedSyntax;
+//     OptionStrict = InitialOptionStrict || UseExtendedSyntax;
+//     OptionCompareBinary = InitialOptionCompareBinary;
+
+//     lexer = new Tokenizer (input, name, defines);
+       
+//     ifElseStateMachine = new IfElseStateMachine();
+//     tokenizerController = new TokenizerController(lexer);
+       
+//     StringBuilder value = new StringBuilder ();
+//     try {
+//             if (yacc_verbose_flag > 0)
+//                     yyparse (lexer, new yydebug.yyDebugSimple ());
+//             else {
+//                     yyparse (lexer);
+//                     cleanup();
+//             }
+//     } 
+//     catch(MBASException e) {
+//             Report.Error(e.code, e.loc, e.Message);
+//     }
+//     catch (Exception e) {
+//             if (Report.Stacktrace)
+//                     Console.WriteLine(e);
+//             Report.Error (29999, lexer.Location, "Parsing error");
+//     }
+
+//     RootContext.VerifyImports();
+
+//     return Report.Errors;
+// }
+
+// void cleanup()
+// {
+//     try {
+//             ifElseStateMachine.HandleToken(IfElseStateMachine.Token.EOF);
+//     }
+//     catch(ApplicationException) {
+//             throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+//     }
+
+//     if(in_external_source) 
+//             Report.Error (30579, lexer.Location, "'#ExternalSource' directives must end with matching '#End ExternalSource'");
+
+//     if(in_marked_region > 0)
+//             Report.Error (30205, lexer.Location, "'#Region' directive must be followed by a matching '#End Region'");
+// }
+
+void HandleConditionalDirective(IfElseStateMachine.Token tok, BoolLiteral expr)
+{
+       try {
+               tokenizerController.PositionTokenizerCursor(tok, expr);
+       }
+       catch(ApplicationException) {
+               tok = IfElseStateMachine.Token.EOF;
+               try {
+                       ifElseStateMachine.HandleToken(tok);
+               }
+               catch(ApplicationException) {
+                       throw new MBASException(ifElseStateMachine.Error, lexer.Location, ifElseStateMachine.ErrString);
+               }
+       }
+}
+/* end end end */
+
+// <summary>
+//   Given the @class_name name, it creates a fully qualified name
+//   based on the containing declaration space
+// </summary>
+MemberName
+MakeName (MemberName class_name)
+{
+       string ns = current_namespace.FullName;
+
+       if (current_container.Name == ""){
+               if (ns != "")
+                       return new MemberName (new MemberName (ns), class_name);
+               else
+                       return class_name;
+       } else {
+               return new MemberName (current_container.MemberName, class_name);
+       }
+}
+
+}
diff --git a/mcs/bmcs/mb-tokenizer.cs b/mcs/bmcs/mb-tokenizer.cs
new file mode 100644 (file)
index 0000000..45e41cc
--- /dev/null
@@ -0,0 +1,1096 @@
+//
+// Mono.MonoBASIC.Tokenizer.cs: The Tokenizer for the MonoBASIC compiler
+//
+// Author: A Rafael D Teixeira (rafaelteixeirabr@hotmail.com)
+//        
+// Based on cs-tokenizer.cs by Miguel de Icaza (miguel@gnu.org)
+//
+// Licensed under the terms of the GNU GPL
+//
+// Copyright (C) 2001 A Rafael D Teixeira
+//
+
+namespace Mono.CSharp
+{
+       using System;
+       using System.Text;
+       using System.Collections;
+       using System.IO;
+       using System.Globalization;
+       //      using Mono.Languages;
+       using Mono.CSharp;
+       
+       /// <summary>
+       ///    Tokenizer for MonoBASIC source code. 
+       /// </summary>
+       
+       public class Tokenizer : yyParser.yyInput
+       {
+               SeekableStreamReader reader;
+               SourceFile file_name;
+               SourceFile ref_name;
+               int ref_line = 0;
+               int line = 0;
+               int col = 1;
+               public int current_token = Token.ERROR;
+               bool handle_get_set = false;
+               bool cant_have_a_type_character = false;
+
+               public int ExpandedTabsSize = 4; 
+
+               public string location {
+                       get {
+                               string det;
+
+                               if (current_token == Token.ERROR)
+                                       det = "detail: " + error_details;
+                               else
+                                       det = "";
+                               
+                               return "Line:     "+line+" Col: "+col + "\n" +
+                                      "VirtLine: "+ref_line +
+                                      " Token: "+current_token + " " + det;
+                       }
+               }
+
+               public bool properties {
+                       get {
+                               return handle_get_set;
+                       }
+
+                       set {
+                               handle_get_set = value;
+                       }
+                }
+               
+               //
+               // Class variables
+               // 
+               static Hashtable keywords;
+               static NumberStyles styles;
+               static NumberFormatInfo csharp_format_info;
+               
+               //
+               // Values for the associated token returned
+               //
+               StringBuilder number;
+               int putback_char = -1;
+               Object val;
+               
+               //
+               // Details about the error encoutered by the tokenizer
+               //
+               string error_details;
+               
+               public string error {
+                       get {
+                               return error_details;
+                       }
+               }
+
+//             public string Source {
+//                     get {
+//                             return file_name;
+//                     }
+
+//                     set {
+//                             file_name = value;
+//                             ref_name = value;
+//                             //Location.SetCurrentSource(file_name);
+//                     }
+//             }
+
+//             public string EffectiveSource {
+//                     get {
+//                             return ref_name;
+//                     }
+//                     set {
+//                             ref_name = value;
+//                             //Location.SetCurrentSource(ref_name);
+//                     }
+//             }
+
+               public int Line {
+                       get {
+                               return line;
+                       }
+               }
+
+               public int EffectiveLine {
+                       get {
+                               return ref_line;
+                       }
+                       set {
+                               ref_line = value;
+                       }
+               }
+
+               public int Col {
+                       get {
+                               return col;
+                       }
+               }
+               
+               static void initTokens ()
+               {
+                       keywords = new Hashtable ();
+
+                       keywords.Add ("addhandler", Token.ADDHANDLER);
+                       keywords.Add ("addressof", Token.ADDRESSOF);
+                       keywords.Add ("alias", Token.ALIAS);
+                       keywords.Add ("and", Token.AND);
+                       keywords.Add ("andalso", Token.ANDALSO);
+                       keywords.Add ("ansi", Token.ANSI);
+                       keywords.Add ("as", Token.AS);
+                       keywords.Add ("assembly", Token.ASSEMBLY);
+                       keywords.Add ("auto", Token.AUTO);
+                       keywords.Add ("binary", Token.BINARY); // Not a VB.NET Keyword 
+                       keywords.Add ("boolean", Token.BOOLEAN);
+                       keywords.Add ("byref", Token.BYREF);
+                       keywords.Add ("byte", Token.BYTE);
+                       keywords.Add ("byval", Token.BYVAL);
+                       keywords.Add ("call", Token.CALL);
+                       keywords.Add ("case", Token.CASE);
+                       keywords.Add ("catch", Token.CATCH);
+                       keywords.Add ("cbool", Token.CBOOL);
+                       keywords.Add ("cbyte", Token.CBYTE);
+                       keywords.Add ("cchar", Token.CCHAR);
+                       keywords.Add ("cdate", Token.CDATE);
+                       keywords.Add ("cdec", Token.CDEC);
+                       keywords.Add ("cdbl", Token.CDBL);
+                       keywords.Add ("char", Token.CHAR);
+                       keywords.Add ("cint", Token.CINT);
+                       keywords.Add ("class", Token.CLASS);
+                       keywords.Add ("clng", Token.CLNG);
+                       keywords.Add ("cobj", Token.COBJ);
+                       keywords.Add ("compare", Token.COMPARE); // Not a VB.NET Keyword
+                       keywords.Add ("const", Token.CONST);
+                       keywords.Add ("cshort", Token.CSHORT);
+                       keywords.Add ("csng", Token.CSNG);
+                       keywords.Add ("cstr", Token.CSTR);
+                       keywords.Add ("ctype", Token.CTYPE);
+                       keywords.Add ("date", Token.DATE);
+                       keywords.Add ("decimal", Token.DECIMAL);
+                       keywords.Add ("declare", Token.DECLARE);
+                       keywords.Add ("default", Token.DEFAULT);
+                       keywords.Add ("delegate", Token.DELEGATE);
+                       keywords.Add ("dim", Token.DIM);
+                       keywords.Add ("directcast", Token.DIRECTCAST);                  
+                       keywords.Add ("do", Token.DO);
+                       keywords.Add ("double", Token.DOUBLE);
+                       keywords.Add ("each", Token.EACH);
+                       keywords.Add ("else", Token.ELSE);
+                       keywords.Add ("elseif", Token.ELSEIF);
+                       keywords.Add ("end", Token.END);
+                       keywords.Add ("endif", Token.ENDIF); // An unused VB.NET keyword
+                       keywords.Add ("enum", Token.ENUM);
+                       keywords.Add ("erase", Token.ERASE);
+                       keywords.Add ("error", Token.ERROR);
+                       keywords.Add ("event", Token.EVENT);
+                       keywords.Add ("exit", Token.EXIT);
+                       keywords.Add ("explicit", Token.EXPLICIT); // Not a VB.NET keyword 
+                       keywords.Add ("false", Token.FALSE);
+                       keywords.Add ("finally", Token.FINALLY);
+                       keywords.Add ("for", Token.FOR);
+                       keywords.Add ("friend", Token.FRIEND);
+                       keywords.Add ("function", Token.FUNCTION);
+                       keywords.Add ("get", Token.GET);
+                       keywords.Add ("gettype", Token.GETTYPE);
+                       keywords.Add ("gosub", Token.GOSUB); // An unused VB.NET keyword 
+                       keywords.Add ("goto", Token.GOTO);
+                       keywords.Add ("handles", Token.HANDLES);
+                       keywords.Add ("if", Token.IF);
+                       keywords.Add ("implements", Token.IMPLEMENTS);
+                       keywords.Add ("imports", Token.IMPORTS);
+                       keywords.Add ("in", Token.IN);
+                       keywords.Add ("inherits", Token.INHERITS);
+                       keywords.Add ("integer", Token.INTEGER);
+                       keywords.Add ("interface", Token.INTERFACE);
+                       keywords.Add ("is", Token.IS);
+                       keywords.Add ("let ", Token.LET ); // An unused VB.NET keyword
+                       keywords.Add ("lib ", Token.LIB );
+                       keywords.Add ("like ", Token.LIKE );
+                       keywords.Add ("long", Token.LONG);
+                       keywords.Add ("loop", Token.LOOP);
+                       keywords.Add ("me", Token.ME);
+                       keywords.Add ("mod", Token.MOD);
+                       keywords.Add ("module", Token.MODULE);
+                       keywords.Add ("mustinherit", Token.MUSTINHERIT);
+                       keywords.Add ("mustoverride", Token.MUSTOVERRIDE);
+                       keywords.Add ("mybase", Token.MYBASE);
+                       keywords.Add ("myclass", Token.MYCLASS);
+                       keywords.Add ("namespace", Token.NAMESPACE);
+                       keywords.Add ("new", Token.NEW);
+                       keywords.Add ("next", Token.NEXT);
+                       keywords.Add ("not", Token.NOT);
+                       keywords.Add ("nothing", Token.NOTHING);
+                       keywords.Add ("notinheritable", Token.NOTINHERITABLE);
+                       keywords.Add ("notoverridable", Token.NOTOVERRIDABLE);
+                       keywords.Add ("object", Token.OBJECT);
+                       keywords.Add ("off", Token.OFF); // Not a VB.NET Keyword 
+                       keywords.Add ("on", Token.ON);
+                       keywords.Add ("option", Token.OPTION);
+                       keywords.Add ("optional", Token.OPTIONAL);
+                       keywords.Add ("or", Token.OR);
+                       keywords.Add ("orelse", Token.ORELSE);
+                       keywords.Add ("overloads", Token.OVERLOADS);
+                       keywords.Add ("overridable", Token.OVERRIDABLE);
+                       keywords.Add ("overrides", Token.OVERRIDES);
+                       keywords.Add ("paramarray", Token.PARAM_ARRAY);
+                       keywords.Add ("preserve", Token.PRESERVE);
+                       keywords.Add ("private", Token.PRIVATE);
+                       keywords.Add ("property", Token.PROPERTY);
+                       keywords.Add ("protected", Token.PROTECTED);
+                       keywords.Add ("public", Token.PUBLIC);
+                       keywords.Add ("raiseevent", Token.RAISEEVENT);
+                       keywords.Add ("readonly", Token.READONLY);
+                       keywords.Add ("redim", Token.REDIM);
+                       keywords.Add ("rem", Token.REM);
+                       keywords.Add ("removehandler", Token.REMOVEHANDLER);
+                       keywords.Add ("resume", Token.RESUME);
+                       keywords.Add ("return", Token.RETURN);
+                       keywords.Add ("select", Token.SELECT);
+                       keywords.Add ("set", Token.SET);
+                       keywords.Add ("shadows", Token.SHADOWS);
+                       keywords.Add ("shared", Token.SHARED);
+                       keywords.Add ("short", Token.SHORT);
+                       keywords.Add ("single", Token.SINGLE);
+                       keywords.Add ("sizeof", Token.SIZEOF); // Not a VB.NET Keyword 
+                       keywords.Add ("static", Token.STATIC);
+                       keywords.Add ("step", Token.STEP);
+                       keywords.Add ("stop", Token.STOP);
+                       keywords.Add ("strict", Token.STRICT); // Not a VB.NET Keyword 
+                       keywords.Add ("string", Token.STRING);
+                       keywords.Add ("structure", Token.STRUCTURE);
+                       keywords.Add ("sub", Token.SUB);
+                       keywords.Add ("synclock", Token.SYNCLOCK);
+                       keywords.Add ("text", Token.TEXT); // Not a VB.NET Keyword
+                       keywords.Add ("then", Token.THEN);
+                       keywords.Add ("throw", Token.THROW);
+                       keywords.Add ("to", Token.TO);
+                       keywords.Add ("true", Token.TRUE);
+                       keywords.Add ("try", Token.TRY);
+                       keywords.Add ("typeof", Token.TYPEOF);
+                       keywords.Add ("unicode", Token.UNICODE);
+                       keywords.Add ("until", Token.UNTIL);
+                       keywords.Add ("variant", Token.VARIANT); // An unused VB.NET keyword
+                       keywords.Add ("wend", Token.WEND); // An unused VB.NET keyword
+                       keywords.Add ("when", Token.WHEN);
+                       keywords.Add ("while", Token.WHILE);
+                       keywords.Add ("with", Token.WITH);
+                       keywords.Add ("withevents", Token.WITHEVENTS);
+                       keywords.Add ("writeonly", Token.WRITEONLY);
+                       keywords.Add ("xor", Token.XOR);
+
+                       /*
+
+                       if (Parser.UseExtendedSyntax){
+                               keywords.Add ("yield", Token.YIELD);
+                       }
+                       */
+
+
+               }
+
+               static Tokenizer ()
+               {
+                       initTokens ();
+                       csharp_format_info = new NumberFormatInfo ();
+                       csharp_format_info.CurrencyDecimalSeparator = ".";
+                       styles = NumberStyles.AllowExponent | NumberStyles.AllowDecimalPoint;
+               }
+
+               public Tokenizer (SeekableStreamReader input, SourceFile fname, ArrayList defines)
+               {
+                       this.ref_name = fname;
+                       this.file_name = fname;
+
+                       reader = input;
+
+                       // putback an EOL at the beginning of a stream. This is a convenience that 
+                       // allows pre-processor directives to be added to the beginning of a vb file.
+                       putback('\n');
+               }
+
+               bool is_keyword (string name)
+               {
+                       bool res;
+                       name = name.ToLower();
+
+                       res = keywords.Contains(name);
+                       if ((name == "GET" || name == "SET") && handle_get_set == false)
+                               return false;
+                       return res;
+               }
+
+               int getKeyword (string name)
+               {
+                       return (int) (keywords [name.ToLower()]);
+               }
+               
+               public Location Location {
+                       get {
+                               return new Location (ref_line);
+                       }
+               }
+               
+               public bool PropertyParsing {
+                       get {
+                               return handle_get_set;
+                       }
+
+                       set {
+                               handle_get_set = value;
+                       }
+                }
+                               
+               static bool is_identifier_start_character (char c)
+               {
+                       return Char.IsLetter (c) || c == '_' ;
+               }
+
+               static bool is_identifier_part_character (char c)
+               {
+                       return (Char.IsLetter (c) || Char.IsDigit (c) || c == '_');
+               }
+
+               public static bool IsValidIdentifier (string s)
+               {
+                       if (s == null || s.Length == 0)
+                               return false;
+                       
+                       if (!is_identifier_start_character (s [0]))
+                               return false;
+                       
+                       for (int i = 1; i < s.Length; i ++)
+                               if (! is_identifier_part_character (s [i]))
+                                       return false;
+                       
+                       return true;
+               }
+
+               int is_punct (char c, ref bool doread)
+               {
+                       int d;
+                       int t;
+
+                       doread = false;
+                       
+                       error_details = c.ToString();
+                       
+                       d = peekChar ();
+                       
+                       switch (c){
+                       case '[':
+                               return Token.OPEN_BRACKET;
+                       case ']':
+                               return Token.CLOSE_BRACKET;
+                       case '{':
+                               return Token.OPEN_BRACE;
+                       case '}':
+                               return Token.CLOSE_BRACE;                               
+                       case '(':
+                               return Token.OPEN_PARENS;
+                       case ')':
+                               return Token.CLOSE_PARENS;
+                       case ',':
+                               return Token.COMMA;
+                       case '?':
+                               return Token.INTERR;
+                       case '!':
+                               if (is_identifier_start_character((char)d) || cant_have_a_type_character)
+                                       return Token.EXCLAMATION;
+                               return Token.SINGLETYPECHAR;
+                       case '$':
+                               if (cant_have_a_type_character)
+                                       return Token.ERROR;
+                               return Token.DOLAR_SIGN;
+                       case '@':
+                               if (cant_have_a_type_character)
+                                       return Token.ERROR;
+                               return Token.AT_SIGN;
+                       case '%':
+                               if (cant_have_a_type_character)
+                                       return Token.ERROR;
+                               return Token.PERCENT;
+                       case '#':
+                               if(tokens_seen)
+                               {
+                                       if (cant_have_a_type_character) 
+                                               return ExtractDateTimeLiteral();
+                                       else
+                                               return Token.NUMBER_SIGN;
+                               }
+                               else 
+                               {
+                                       tokens_seen = true;
+                                       return Token.HASH;
+                               } 
+                       case '&':
+                               if (!cant_have_a_type_character)
+                                       return Token.LONGTYPECHAR;
+                               t = handle_integer_literal_in_other_bases(d);
+                               if (t == Token.NONE) {
+                                       t = Token.OP_CONCAT;
+                               }
+                               return t;                       
+                       }
+
+                       if (c == '+'){
+                               if (d == '+')
+                                       t = Token.OP_INC;
+                               else 
+                                       return Token.PLUS;
+                               doread = true;
+                               return t;
+                       }
+                       if (c == '-'){
+                               return Token.MINUS;
+                       }
+
+                       if (c == '='){
+                               return Token.ASSIGN;
+                       }
+
+                       if (c == '*'){
+                               return Token.STAR;
+                       }
+
+                       if (c == '/'){
+                               return Token.DIV;
+                       }
+
+                       if (c == '\\'){
+                               return Token.OP_IDIV;
+                       }
+
+                       if (c == '^'){
+                               return Token.OP_EXP;
+                       }
+
+                       if (c == '<'){
+                               if (d == '>')
+                               {
+                                       doread = true;
+                                       return Token.OP_NE;
+                               }
+                               if (d == '='){
+                                       doread = true;
+                                       return Token.OP_LE;
+                               }
+                               if (d == '<')
+                               {
+                                       doread = true;
+                                       return Token.OP_SHIFT_LEFT;
+                               }
+                               return Token.OP_LT;
+                       }
+
+                       if (c == '>'){
+                               if (d == '='){
+                                       doread = true;
+                                       return Token.OP_GE;
+                               }
+                               if (d == '>')
+                               {
+                                       doread = true;
+                                       return Token.OP_SHIFT_RIGHT;
+                               }
+                               return Token.OP_GT;
+                       }
+                       
+                       if (c == ':'){
+                               if (d == '='){
+                                       doread = true;
+                                       return Token.ATTR_ASSIGN;
+                               }
+                               return Token.COLON;
+                       }                       
+                       
+                       return Token.ERROR;
+               }
+
+               bool decimal_digits (int c)
+               {
+                       int d;
+                       bool seen_digits = false;
+                       
+                       if (c != -1)
+                               number.Append ((char) c);
+                       
+                       while ((d = peekChar ()) != -1){
+                               if (Char.IsDigit ((char)d)){
+                                       number.Append ((char) d);
+                                       getChar ();
+                                       seen_digits = true;
+                               } else
+                                       break;
+                       }
+                       return seen_digits;
+               }
+
+               
+               int real_type_suffix (int c)
+               {
+                       int t;
+                       
+                       switch (c){
+                       case 'F': case 'f':
+                               t =  Token.LITERAL_SINGLE;
+                               break;
+                       case 'R': case 'r':
+                               t = Token.LITERAL_DOUBLE;
+                               break;
+                       case 'D': case 'd':
+                                t= Token.LITERAL_DECIMAL;
+                               break;
+                       default:
+                               return Token.NONE;
+                       }
+                       getChar ();
+                       return t;
+               }
+
+               int integer_type_suffix (int c)
+               {
+                       int t;
+                       
+                       try {
+                       
+                               switch (c){
+                               case 'S': case 's':
+                                       t =  Token.LITERAL_INTEGER; // SHORT ?
+                                       val = ((IConvertible)val).ToInt16(null);
+                                       break;
+                               case 'I': case 'i':
+                                       t = Token.LITERAL_INTEGER;
+                                       val = ((IConvertible)val).ToInt32(null);
+                                       break;
+                               case 'L': case 'l':
+                                        t= Token.LITERAL_INTEGER; // LONG ?
+                                        val = ((IConvertible)val).ToInt64(null);
+                                       break;
+                               default:
+                                       if ((long)val <= System.Int32.MaxValue &&
+                                               (long)val >= System.Int32.MinValue) {
+                                               val = ((IConvertible)val).ToInt32(null);
+                                               return Token.LITERAL_INTEGER;
+                                       } else {
+                                               val = ((IConvertible)val).ToInt64(null);
+                                               return Token.LITERAL_INTEGER; // LONG ?
+                                       }
+                               }
+                               getChar ();
+                               return t;
+                       } catch (Exception e) {
+                               val = e.ToString();
+                               return Token.ERROR;
+                       }
+               }
+               
+               int adjust_real (int t)
+               {
+                       string s = number.ToString ();
+
+                       switch (t){
+                       case Token.LITERAL_DECIMAL:
+                               val = new System.Decimal ();
+                               val = System.Decimal.Parse (
+                                       s, styles, csharp_format_info);
+                               break;
+                       case Token.LITERAL_DOUBLE:
+                               val = new System.Double ();
+                               val = System.Double.Parse (
+                                       s, styles, csharp_format_info);
+                               break;
+                       case Token.LITERAL_SINGLE:
+                               val = new System.Double ();
+                               val = (float) System.Double.Parse (
+                                       s, styles, csharp_format_info);
+                               break;
+
+                       case Token.NONE:
+                               val = new System.Double ();
+                               val = System.Double.Parse (
+                                       s, styles, csharp_format_info);
+                               t = Token.LITERAL_DOUBLE;
+                               break;
+                       }
+                       return t;
+               }
+
+               long hex_digits ()
+               {
+                       StringBuilder hexNumber = new StringBuilder ();
+                       
+                       int d;
+
+                       while ((d = peekChar ()) != -1){
+                               char e = Char.ToUpper ((char) d);
+                               
+                               if (Char.IsDigit (e) || (e >= 'A' && e <= 'F')){
+                                       hexNumber.Append (e);
+                                       getChar ();
+                               } else
+                                       break;
+                       }
+                       return System.Int64.Parse (hexNumber.ToString(), NumberStyles.HexNumber);
+               }
+
+               long octal_digits ()
+               {
+                       long valueToReturn = 0;
+                       
+                       int d;
+
+                       while ((d = peekChar ()) != -1){
+                               char e = (char)d;                       
+                               if (Char.IsDigit (e) && (e < '8')){
+                                       valueToReturn *= 8;
+                                       valueToReturn += (d - (int)'0');
+                                       getChar ();
+                               } else
+                                       break;
+                       }
+                       
+                       return valueToReturn;
+               }
+
+               int handle_integer_literal_in_other_bases(int peek)
+               {
+                       if (peek == 'h' || peek == 'H'){
+                               getChar ();
+                               val = hex_digits ();
+                               return integer_type_suffix (peekChar ());
+                       }
+                       
+                       if (peek == 'o' || peek == 'O'){
+                               getChar ();
+                               val = octal_digits ();
+                               return integer_type_suffix (peekChar ());
+                       }
+                       
+                       return Token.NONE;
+               }
+               
+               //
+               // Invoked if we know we have .digits or digits
+               //
+               int is_number (int c)
+               {
+                       bool is_real = false;
+                       number = new StringBuilder ();
+                       int type;
+
+                       number.Length = 0;
+
+                       if (Char.IsDigit ((char)c)){
+                               decimal_digits (c);
+                               c = peekChar ();
+                       }
+
+                       //
+                       // We need to handle the case of
+                       // "1.1" vs "1.ToString()" (LITERAL_SINGLE vs NUMBER DOT IDENTIFIER)
+                       //
+                       if (c == '.'){
+                               if (decimal_digits (getChar())){
+                                       is_real = true;
+                                       c = peekChar ();
+                               } else {
+                                       putback ('.');
+                                       number.Length -= 1;
+                                       val = System.Int64.Parse(number.ToString());
+                                       return integer_type_suffix('.');
+                               }
+                       }
+                       
+                       if (c == 'e' || c == 'E'){
+                               is_real = true;
+                               number.Append ("e");
+                               getChar ();
+                               
+                               c = peekChar ();
+                               if (c == '+'){
+                                       number.Append ((char) c);
+                                       getChar ();
+                                       c = peekChar ();
+                               } else if (c == '-'){
+                                       number.Append ((char) c);
+                                       getChar ();
+                                       c = peekChar ();
+                               }
+                               decimal_digits (-1);
+                               c = peekChar ();
+                       }
+
+                       type = real_type_suffix (c);
+                       if (type == Token.NONE && !is_real){
+                               val = System.Int64.Parse(number.ToString());
+                               return integer_type_suffix(c);
+                       }
+                       
+                       return adjust_real (type);
+               }
+                       
+               int getChar ()
+               {
+                       if (putback_char != -1){
+                               int x = putback_char;
+                               putback_char = -1;
+
+                               return x;
+                       }
+                       return reader.Read ();
+               }
+
+               int peekChar ()
+               {
+                       if (putback_char != -1)
+                               return putback_char;
+                       return reader.Peek ();
+               }
+
+               void putback (int c)
+               {
+                       if (putback_char != -1)
+                               throw new Exception ("This should not happen putback on putback");
+                       putback_char = c;
+               }
+
+               public bool advance ()
+               {
+                       return current_token != Token.EOF ;
+               }
+
+               public Object Value {
+                       get {
+                               return val;
+                       }
+               }
+
+               public Object value ()
+               {
+                       return val;
+               }
+
+               private bool IsEOL(int currentChar)
+               {
+                       bool retVal;
+                       
+                       if (currentChar ==  0x0D) {
+                               if (peekChar() ==  0x0A) // if it is a CR-LF pair consume LF also
+                                       getChar();
+
+                               retVal = true;
+                       }
+                       else {
+                               retVal = (currentChar ==  -1 || currentChar ==  0x0A || currentChar ==  0x2028 || currentChar ==  0x2029);
+                       }
+
+                       if(retVal) {
+                               nextLine();
+                       }
+
+                       return retVal;
+               }
+
+               private int DropComments()              
+               {
+                       int d;
+                       while (!IsEOL(d = getChar ()))
+                               col++;
+
+                       return Token.EOL;
+               }       
+                       
+               public int token ()
+               {
+                       int lastToken = current_token;
+                       do
+                       {
+                               current_token = xtoken ();
+                               if (current_token == 0) 
+                                       return Token.EOF;
+                               if (current_token == Token.REM)
+                                       current_token = DropComments();
+                       } while (lastToken == Token.EOL && current_token == Token.EOL);
+
+                       // Console.WriteLine ("Token = " + val);
+
+                       return current_token;
+               }
+
+               private string GetIdentifier()
+               {
+                       int c = getChar();
+                       if (is_identifier_start_character ((char) c))
+                               return GetIdentifier(c);
+                       else
+                               return null;
+               }
+
+               private string GetIdentifier(int c)
+               {
+                       StringBuilder id = new StringBuilder ();
+
+                       id.Append ((char) c);
+                               
+                       while ((c = peekChar ()) != -1) 
+                       {
+                               if (is_identifier_part_character ((char) c))
+                               {
+                                       id.Append ((char)getChar ());
+                                       col++;
+                               } 
+                               else 
+                                       break;
+                       }
+                       
+                       cant_have_a_type_character = false;
+                       
+                       return id.ToString();
+               }
+
+               private bool is_doublequote(int currentChar)
+               {
+                       return (currentChar == '"' || 
+                                       currentChar == 0x201C || // unicode left double-quote character
+                                       currentChar == 0x201D);  // unicode right double-quote character
+               }
+               
+               private bool is_whitespace(int c)
+               {
+                       return (c == ' ' || c == '\t' || c == '\v' || c == '\r' || c == 0xa0);
+               }
+               
+               private bool tokens_seen = false;
+               
+               private void nextLine()
+               {
+                       cant_have_a_type_character = true;
+                       line++;
+                       ref_line++;
+                       col = 0;
+                       tokens_seen = false;
+               }
+
+               public int xtoken ()
+               {
+                       int t;
+                       bool doread = false;
+                       int c;
+
+                       val = null;
+                       for (;(c = getChar ()) != -1; col++) {
+                       
+                               // Handle line continuation character
+                               if (c == '_') 
+                               {
+                                       int d = peekChar();
+                                       if (!is_identifier_part_character((char)d)) {
+                                               while ((c = getChar ()) != -1 && !IsEOL(c)) {}
+                                               c = getChar ();                 
+                                       }               
+                               }
+
+                               // white space
+                               if (is_whitespace(c)) {
+                                       // expand tabs for location
+                                       if (c == '\t')
+                                               col = (((col + ExpandedTabsSize) / ExpandedTabsSize) * ExpandedTabsSize) - 1;
+                                       cant_have_a_type_character = true;
+                                       continue;
+                               }
+                               
+                               // Handle line comments.
+                               if (c == '\'')
+                                       return Token.REM;                                       
+                               
+                               // Handle EOL.
+                               if (IsEOL(c))
+                               {
+                                       if (current_token == Token.EOL) // if last token was also EOL keep skipping
+                                               continue;
+                                       return Token.EOL;
+                               }
+                               
+                               // Handle escaped identifiers
+                               if (c == '[')
+                               {
+                                       if ((val = GetIdentifier()) == null)
+                                               break;
+                                       if ((c = getChar()) != ']')
+                                               break;
+                                       tokens_seen = true;
+                                       return Token.IDENTIFIER;
+                               }
+
+                               // Handle unescaped identifiers
+                               if (is_identifier_start_character ((char) c))
+                               {
+                                       string id;
+                                       if ((id = GetIdentifier(c)) == null)
+                                               break;
+                                       val = id;
+                                       tokens_seen = true;
+                                       if (is_keyword(id) && (current_token != Token.DOT))
+                                               return getKeyword(id);
+                                       return Token.IDENTIFIER;
+                               }
+
+                               // Treat string literals
+                               if (is_doublequote(c)) {
+                                       cant_have_a_type_character = true;
+                                       return ExtractStringOrCharLiteral(c);
+                               }
+                       
+                               // handle numeric literals
+                               if (c == '.')
+                               {
+                                       cant_have_a_type_character = true;
+                                       tokens_seen = true;
+                                       if (Char.IsDigit ((char) peekChar ()))
+                                               return is_number (c);
+                                       return Token.DOT;
+                               }
+                               
+                               if (Char.IsDigit ((char) c))
+                               {
+                                       cant_have_a_type_character = true;
+                                       tokens_seen = true;
+                                       return is_number (c);
+                               }
+
+                               if ((t = is_punct ((char)c, ref doread)) != Token.ERROR) {
+                                       cant_have_a_type_character = true;
+
+                                       if (t == Token.NONE)
+                                               continue;
+                                               
+                                       if (doread){
+                                               getChar ();
+                                               col++;
+                                       }
+                                       tokens_seen = true;
+                                       return t;
+                               }
+                               
+                               error_details = ((char)c).ToString ();
+                               return Token.ERROR;
+                       }
+
+                       if (current_token != Token.EOL) // if last token wasn't EOL send it before EOF
+                               return Token.EOL;
+                       
+                       return Token.EOF;
+               }
+
+               private int ExtractDateTimeLiteral()
+               {
+                       int c;
+                       
+                       StringBuilder sb = new StringBuilder();
+                       for (;(c = getChar ()) != -1; col++)
+                       {
+                               if (c == '#') {
+                                       val = ParseDateLiteral(sb);
+                                       return Token.LITERAL_DATE;
+                               }
+                               if (IsEOL(c)) {
+                                       break;
+                               } 
+                               if (c == '-')
+                                       c = '/';
+                               sb.Append((char)c);
+                       }
+                       return Token.ERROR;
+               }
+               
+               private int ExtractStringOrCharLiteral(int c)
+               {
+                       StringBuilder s = new StringBuilder ();
+
+                       tokens_seen = true;
+
+                       while ((c = getChar ()) != -1){
+                               if (is_doublequote(c)){
+                                       if (is_doublequote(peekChar()))
+                                               getChar();
+                                       else {
+                                               //handle Char Literals
+                                               if (peekChar() == 'C' || peekChar() == 'c') {
+                                                       getChar();
+                                                       if (s.Length == 1) {
+                                                               val = s[0];
+                                                               return Token.LITERAL_CHARACTER;
+                                                       } else {
+                                                               val = "Incorrect length for a character literal";
+                                                               return Token.ERROR;
+                                                       }                                                       
+                                               } else {
+                                                       val = s.ToString ();
+                                                       return Token.LITERAL_STRING;
+                                               }
+                                       }
+                               }
+
+                               if (IsEOL(c)) {
+                                       return Token.ERROR;
+                               }
+                       
+                               s.Append ((char) c);
+                       }
+                                       
+                       return Token.ERROR;
+               }
+
+               static IFormatProvider enUSculture = new CultureInfo("en-US", true);
+
+               private DateTime ParseDateLiteral(StringBuilder value)
+               {
+                       try
+                       {
+                               return DateTime.Parse(value.ToString(),
+                                                 enUSculture,
+                                                 DateTimeStyles.NoCurrentDateDefault | DateTimeStyles.AllowWhiteSpaces);
+                       }
+                       catch (FormatException ex)
+                       {
+                               //TODO: What is the correct error number and message?
+                               Report.Error (1, Location, string.Format("Invalid date literal '{0}'", value.ToString()) 
+                                       + Environment.NewLine + ex.ToString());
+                       }
+                       catch (Exception)
+                       {
+                               Report.Error (1, Location, "Error parsing date literal");       //TODO: What is the correct error number and message?
+                       }
+                       return new DateTime();
+               }
+               public void PositionCursorAtNextPreProcessorDirective()
+               {
+                       int t;
+                       
+                       for(t = token(); t != Token.HASH && t != Token.EOF; t = token());
+
+                       if(t == Token.EOF)
+                               throw new ApplicationException("Unexpected EOF while looking for a pre-processor directive");
+                       
+                       if(t == Token.HASH) {
+                               tokens_seen = false;
+                               putback('#');
+                       }
+               }
+
+               public void cleanup ()
+               {
+                       // FIXME;
+               }
+
+               public static void Cleanup () 
+               {
+               }
+
+       }
+}
diff --git a/mcs/bmcs/modifiers.cs b/mcs/bmcs/modifiers.cs
new file mode 100644 (file)
index 0000000..8d6544e
--- /dev/null
@@ -0,0 +1,252 @@
+//
+// modifiers.cs: Modifier handling.
+// 
+using System;
+using System.Reflection;
+
+namespace Mono.CSharp {
+       public class Modifiers {
+
+               //
+               // The ordering of the following 4 constants
+               // has been carefully done.
+               //
+               public const int PROTECTED = 0x0001;
+               public const int PUBLIC    = 0x0002;
+               public const int PRIVATE   = 0x0004;
+               public const int INTERNAL  = 0x0008;
+               public const int NEW       = 0x0010;
+               public const int ABSTRACT  = 0x0020;
+               public const int SEALED    = 0x0040;
+               public const int STATIC    = 0x0080;
+               public const int READONLY  = 0x0100;
+               public const int VIRTUAL   = 0x0200;
+               public const int OVERRIDE  = 0x0400;
+               public const int EXTERN    = 0x0800;
+               public const int VOLATILE  = 0x1000;
+               public const int UNSAFE    = 0x2000;
+               public const int WRITEONLY = 0x04000;
+               public const int SHADOWS   = 0x08000;
+               public const int DEFAULT   = 0x10000;
+               public const int NONVIRTUAL= 0x20000;
+               private const int TOP      = 0x20000;
+
+               //
+               // We use this internally to flag that the method contains an iterator
+               //
+               public const int METHOD_YIELDS = 0x8000;
+               public const int METHOD_GENERIC = 0x10000;
+
+               public const int Accessibility =
+                       PUBLIC | PROTECTED | INTERNAL | PRIVATE;
+               public const int AllowedExplicitImplFlags =
+                       UNSAFE | EXTERN;
+               
+               static public string Name (int i)
+               {
+                       string s = "";
+                       
+                       switch (i) {
+                       case Modifiers.NEW:
+                               s = "new"; break;
+                       case Modifiers.PUBLIC:
+                               s = "public"; break;
+                       case Modifiers.PROTECTED:
+                               s = "protected"; break;
+                       case Modifiers.INTERNAL:
+                               s = "internal"; break;
+                       case Modifiers.PRIVATE:
+                               s = "private"; break;
+                       case Modifiers.ABSTRACT:
+                               s = "abstract"; break;
+                       case Modifiers.SEALED:
+                               s = "sealed"; break;
+                       case Modifiers.STATIC:
+                               s = "static"; break;
+                       case Modifiers.READONLY:
+                               s = "readonly"; break;
+                       case Modifiers.VIRTUAL:
+                               s = "virtual"; break;
+                       case Modifiers.OVERRIDE:
+                               s = "override"; break;
+                       case Modifiers.EXTERN:
+                               s = "extern"; break;
+                       case Modifiers.VOLATILE:
+                               s = "volatile"; break;
+                       case Modifiers.UNSAFE:
+                               s = "unsafe"; break;
+                       }
+
+                       return s;
+               }
+
+               public static TypeAttributes TypeAttr (int mod_flags, bool is_toplevel)
+               {
+                       TypeAttributes t = 0;
+
+                       if (is_toplevel){
+                               if ((mod_flags & PUBLIC) != 0)
+                                       t |= TypeAttributes.Public;
+                               if ((mod_flags & PRIVATE) != 0)
+                                       t |= TypeAttributes.NotPublic;
+                       } else {
+                               if ((mod_flags & PUBLIC) != 0)
+                                       t |= TypeAttributes.NestedPublic;
+                               if ((mod_flags & PRIVATE) != 0)
+                                       t |= TypeAttributes.NestedPrivate;
+                               if ((mod_flags & PROTECTED) != 0 && (mod_flags & INTERNAL) != 0)
+                                       t |= TypeAttributes.NestedFamORAssem;
+                               if ((mod_flags & PROTECTED) != 0)
+                                       t |= TypeAttributes.NestedFamily;
+                               if ((mod_flags & INTERNAL) != 0)
+                                       t |= TypeAttributes.NestedAssembly;
+                       }
+                       
+                       if ((mod_flags & SEALED) != 0)
+                               t |= TypeAttributes.Sealed;
+                       if ((mod_flags & ABSTRACT) != 0)
+                               t |= TypeAttributes.Abstract;
+
+                       return t;
+               }
+               
+               public static TypeAttributes TypeAttr (int mod_flags, TypeContainer caller)
+               {
+                       TypeAttributes t = TypeAttr (mod_flags, caller.IsTopLevel);
+
+                       // If we do not have static constructors, static methods
+                       // can be invoked without initializing the type.
+                       if (!caller.UserDefinedStaticConstructor &&
+                           (caller.Kind != Kind.Interface))
+                               t |= TypeAttributes.BeforeFieldInit;
+                               
+                       return t;
+               }
+
+               public static FieldAttributes FieldAttr (int mod_flags)
+               {
+                       FieldAttributes fa = 0;
+
+                       if ((mod_flags & PUBLIC) != 0)
+                               fa |= FieldAttributes.Public;
+                       if ((mod_flags & PRIVATE) != 0)
+                               fa |= FieldAttributes.Private;
+                       if ((mod_flags & PROTECTED) != 0){
+                               if ((mod_flags & INTERNAL) != 0)
+                                       fa |= FieldAttributes.FamORAssem;
+                               else 
+                                       fa |= FieldAttributes.Family;
+                       } else {
+                               if ((mod_flags & INTERNAL) != 0)
+                                       fa |= FieldAttributes.Assembly;
+                       }
+                       
+                       if ((mod_flags & STATIC) != 0)
+                               fa |= FieldAttributes.Static;
+                       if ((mod_flags & READONLY) != 0)
+                               fa |= FieldAttributes.InitOnly;
+
+                       return fa;
+               }
+
+               public static MethodAttributes MethodAttr (int mod_flags)
+               {
+                       MethodAttributes ma = MethodAttributes.HideBySig;
+
+                       if ((mod_flags & PUBLIC) != 0)
+                               ma |= MethodAttributes.Public;
+                       if ((mod_flags & PRIVATE) != 0)
+                               ma |= MethodAttributes.Private;
+                       if ((mod_flags & PROTECTED) != 0){
+                               if ((mod_flags & INTERNAL) != 0)
+                                       ma |= MethodAttributes.FamORAssem;
+                               else 
+                                       ma |= MethodAttributes.Family;
+                       } else {
+                               if ((mod_flags & INTERNAL) != 0)
+                                       ma |= MethodAttributes.Assembly;
+                       }
+
+                       if ((mod_flags & STATIC) != 0)
+                               ma |= MethodAttributes.Static;
+                       if ((mod_flags & ABSTRACT) != 0){
+                               ma |= MethodAttributes.Abstract | MethodAttributes.Virtual;
+                       }
+                       if ((mod_flags & SEALED) != 0)
+                               ma |= MethodAttributes.Final;
+
+                       if ((mod_flags & VIRTUAL) != 0)
+                               ma |= MethodAttributes.Virtual;
+
+                       if ((mod_flags & OVERRIDE) != 0)
+                               ma |= MethodAttributes.Virtual;
+                       else {
+                               if ((ma & MethodAttributes.Virtual) != 0)
+                                       ma |= MethodAttributes.NewSlot;
+                       }
+                       
+                       return ma;
+               }
+
+               // <summary>
+               //   Checks the object @mod modifiers to be in @allowed.
+               //   Returns the new mask.  Side effect: reports any
+               //   incorrect attributes. 
+               // </summary>
+               public static int Check (int allowed, int mod, int def_access, Location l)
+               {
+                       int invalid_flags  = (~allowed) & mod;
+                       int i;
+
+                       if (invalid_flags == 0){
+                               int a = mod;
+
+                               if ((mod & Modifiers.UNSAFE) != 0){
+                                       if (!RootContext.Unsafe){
+                                               Report.Error (227, l,
+                                                             "Unsafe code requires the -unsafe command " +
+                                                             "line option to be specified");
+                                       }
+                               }
+                               
+                               //
+                               // If no accessibility bits provided
+                               // then provide the defaults.
+                               //
+                               if ((mod & Accessibility) == 0){
+                                       mod |= def_access;
+                                       return mod;
+                               }
+
+                               //
+                               // Make sure that no conflicting accessibility
+                               // bits have been set.  Protected+Internal is
+                               // allowed, that is why they are placed on bits
+                               // 1 and 4 (so the shift 3 basically merges them)
+                               //
+                               a &= 15;
+                               a |= (a >> 3);
+                               a = ((a & 2) >> 1) + (a & 5);
+                               a = ((a & 4) >> 2) + (a & 3);
+                               if (a > 1)
+                                       Report.Error (107, l, "More than one protection modifier specified");
+                               
+                               return mod;
+                       }
+                       
+                       for (i = 1; i <= TOP; i <<= 1){
+                               if ((i & invalid_flags) == 0)
+                                       continue;
+
+                               Error_InvalidModifier (l, Name (i));
+                       }
+
+                       return allowed & mod;
+               }
+
+               public static void Error_InvalidModifier (Location l, string name)
+               {
+                       Report.Error (106, l, "the modifier " + name + " is not valid for this item");
+               }
+       }
+}
diff --git a/mcs/bmcs/module.cs b/mcs/bmcs/module.cs
new file mode 100644 (file)
index 0000000..adbc5f3
--- /dev/null
@@ -0,0 +1,63 @@
+//
+// module.cs: Module handler
+//
+// Author: Rafael Teixeira (rafaelteixeirabr@hotmail.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2002 Rafael Teixeira
+//
+using System;
+using System.Collections;
+using System.Diagnostics.SymbolStore;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Runtime.CompilerServices;
+using Mono.CSharp ;
+
+namespace Mono.CSharp
+{
+       public class Utils
+       {
+               public static void AddSpecializedAttribute(ref Attributes attrs, string attributeName, ArrayList args, Location loc)
+               {
+                       Mono.CSharp.Attribute specialAttr = new Mono.CSharp.Attribute(null, attributeName, args, loc); // Sudha :  passed null for target
+                       ArrayList al = new ArrayList();
+                       al.Add(specialAttr);
+                       if (attrs == null) {
+                               attrs = new Attributes(al);
+                       } else {
+                               attrs.AddAttributes(al);
+                       }
+               }
+       }
+
+       public class VBModule : Class
+       {
+               public new const int AllowedModifiers = Modifiers.PUBLIC |Modifiers.INTERNAL;
+
+               public VBModule (NamespaceEntry ns, TypeContainer parent, MemberName name, int mod,
+                             Attributes attrs, Location l)
+                       : base (ns, parent, name, 0, attrs, l)
+
+               {
+                       if (parent.Parent != null)
+                               Report.Error (30617, l,
+                                       "'Module' statements can occur only at file or namespace level");
+
+                       // overwrite ModFlags
+                       this.ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.INTERNAL, l);
+
+                       // add specialized attribute
+                       Utils.AddSpecializedAttribute(ref attributes, "Microsoft.VisualBasic.CompilerServices.StandardModuleAttribute", null, l);
+               }
+
+
+               public override TypeAttributes TypeAttr 
+               {
+                       get {
+                               return base.TypeAttr | TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.Sealed;
+                       }
+               }
+       }
+}
diff --git a/mcs/bmcs/namespace.cs b/mcs/bmcs/namespace.cs
new file mode 100644 (file)
index 0000000..be26cc1
--- /dev/null
@@ -0,0 +1,662 @@
+//
+// namespace.cs: Tracks namespaces
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc.
+//
+using System;
+using System.Collections;
+
+namespace Mono.CSharp {
+
+       /// <summary>
+       ///   Keeps track of the namespaces defined in the C# code.
+       /// </summary>
+       public class Namespace : IAlias {
+               static ArrayList all_namespaces = new ArrayList ();
+               static Hashtable namespaces_map = new Hashtable ();
+               
+               Namespace parent;
+               string fullname;
+               ArrayList entries;
+               Hashtable namespaces;
+               Hashtable defined_names;
+
+               /// <summary>
+               ///   Constructor Takes the current namespace and the
+               ///   name.  This is bootstrapped with parent == null
+               ///   and name = ""
+               /// </summary>
+               public Namespace (Namespace parent, string name)
+               {
+                       this.parent = parent;
+
+                       string pname = parent != null ? parent.Name : "";
+                               
+                       if (pname == "")
+                               fullname = name;
+                       else
+                               fullname = parent.Name + "." + name;
+
+                       entries = new ArrayList ();
+                       namespaces = new Hashtable ();
+                       defined_names = new Hashtable ();
+
+                       all_namespaces.Add (this);
+                       if (namespaces_map.Contains (fullname))
+                               return;
+                       namespaces_map [fullname] = true;
+               }
+
+               public static bool IsNamespace (string name)
+               {
+                       return namespaces_map [name] != null;
+               }
+               
+               public static Namespace Root = new Namespace (null, "");
+
+               public Namespace GetNamespace (string name, bool create)
+               {
+                       int pos = name.IndexOf ('.');
+
+                       Namespace ns;
+                       string first;
+                       if (pos >= 0)
+                               first = name.Substring (0, pos);
+                       else
+                               first = name;
+
+                       ns = (Namespace) namespaces [first];
+                       if (ns == null) {
+                               if (!create)
+                                       return null;
+
+                               ns = new Namespace (this, first);
+                               namespaces.Add (first, ns);
+                       }
+
+                       if (pos >= 0)
+                               ns = ns.GetNamespace (name.Substring (pos + 1), create);
+
+                       return ns;
+               }
+
+               public static Namespace LookupNamespace (string name, bool create)
+               {
+                       return Root.GetNamespace (name, create);
+               }
+
+               public IAlias Lookup (DeclSpace ds, string name, Location loc)
+               {
+                       IAlias o = Lookup (name);
+
+                       Type t;
+                       DeclSpace tdecl = o as DeclSpace;
+                       if (tdecl != null) {
+                               t = tdecl.DefineType ();
+                               if (t == null)
+                                       return null;
+
+                               if ((ds == null) || ds.CheckAccessLevel (t))
+                                       return new TypeExpression (t, loc);
+                       }
+
+                       Namespace ns = GetNamespace (name, false);
+                       if (ns != null)
+                               return ns;
+
+                       t = TypeManager.LookupType (DeclSpace.MakeFQN (fullname, name));
+                       if ((t == null) || ((ds != null) && !ds.CheckAccessLevel (t)))
+                               return null;
+
+                       return new TypeExpression (t, loc);
+               }
+
+               public void AddNamespaceEntry (NamespaceEntry entry)
+               {
+                       entries.Add (entry);
+               }
+
+               public void DefineName (string name, IAlias o)
+               {
+                       defined_names.Add (name, o);
+               }
+
+               public IAlias Lookup (string name)
+               {
+                       return (IAlias) defined_names [name];
+               }
+
+               static public ArrayList UserDefinedNamespaces {
+                       get {
+                               return all_namespaces;
+                       }
+               }
+
+               /// <summary>
+               ///   The qualified name of the current namespace
+               /// </summary>
+               public string Name {
+                       get {
+                               return fullname;
+                       }
+               }
+
+               /// <summary>
+               ///   The parent of this namespace, used by the parser to "Pop"
+               ///   the current namespace declaration
+               /// </summary>
+               public Namespace Parent {
+                       get {
+                               return parent;
+                       }
+               }
+
+               public static void DefineNamespaces (SymbolWriter symwriter)
+               {
+                       foreach (Namespace ns in all_namespaces) {
+                               foreach (NamespaceEntry entry in ns.entries)
+                                       entry.DefineNamespace (symwriter);
+                       }
+               }
+
+               /// <summary>
+               ///   Used to validate that all the using clauses are correct
+               ///   after we are finished parsing all the files.  
+               /// </summary>
+               public static void VerifyUsing ()
+               {
+                       foreach (Namespace ns in all_namespaces) {
+                               foreach (NamespaceEntry entry in ns.entries)
+                                       entry.VerifyUsing ();
+                       }
+               }
+
+               public override string ToString ()
+               {
+                       if (this == Root)
+                               return "Namespace (<root>)";
+                       else
+                               return String.Format ("Namespace ({0})", Name);
+               }
+
+               bool IAlias.IsType {
+                       get { return false; }
+               }
+
+               TypeExpr IAlias.ResolveAsType (EmitContext ec)
+               {
+                       throw new InvalidOperationException ();
+               }
+       }
+
+       public class NamespaceEntry
+       {
+               Namespace ns;
+               NamespaceEntry parent, implicit_parent;
+               SourceFile file;
+               int symfile_id;
+               Hashtable aliases;
+               ArrayList using_clauses;
+               public bool DeclarationFound = false;
+
+               //
+               // This class holds the location where a using definition is
+               // done, and whether it has been used by the program or not.
+               //
+               // We use this to flag using clauses for namespaces that do not
+               // exist.
+               //
+               public class UsingEntry {
+                       public readonly string Name;
+                       public readonly NamespaceEntry NamespaceEntry;
+                       public readonly Location Location;
+                       
+                       public UsingEntry (NamespaceEntry entry, string name, Location loc)
+                       {
+                               Name = name;
+                               NamespaceEntry = entry;
+                               Location = loc;
+                       }
+
+                       Namespace resolved_ns;
+
+                       public Namespace Resolve ()
+                       {
+                               if (resolved_ns != null)
+                                       return resolved_ns;
+
+                               object resolved = NamespaceEntry.LookupForUsing (Name, Location);
+                               resolved_ns = resolved as Namespace;
+                               return resolved_ns;
+                       }
+               }
+
+               public class AliasEntry {
+                       public readonly string Name;
+                       public readonly MemberName Alias;
+                       public readonly NamespaceEntry NamespaceEntry;
+                       public readonly Location Location;
+                       
+                       public AliasEntry (NamespaceEntry entry, string name, MemberName alias, Location loc)
+                       {
+                               Name = name;
+                               Alias = alias;
+                               NamespaceEntry = entry;
+                               Location = loc;
+                       }
+
+                       IAlias resolved;
+
+                       public IAlias Resolve ()
+                       {
+                               if (resolved != null)
+                                       return resolved;
+
+                               //
+                               // GENERICS: Cope with the expression and not with the string
+                               // this will fail with `using A = Stack<int>'
+                               //
+                               
+                               string alias = Alias.GetTypeName ();
+
+                               resolved = NamespaceEntry.LookupForUsing (alias, Location);
+                               if (resolved == null)
+                                       return null;
+
+                               if (resolved.IsType)
+                                       resolved = new TypeAliasExpression (
+                                               resolved, Alias.TypeArguments, Location);
+
+                               return resolved;
+                       }
+               }
+
+               public NamespaceEntry (NamespaceEntry parent, SourceFile file, string name, Location loc)
+                       : this (parent, file, name, false, loc)
+               { }
+
+               protected NamespaceEntry (NamespaceEntry parent, SourceFile file, string name, bool is_implicit, Location loc)
+               {
+                       this.parent = parent;
+                       this.file = file;
+                       this.IsImplicit = is_implicit;
+                       this.ID = ++next_id;
+
+                       if (!is_implicit && (parent != null))
+                               ns = parent.NS.GetNamespace (name, true);
+                       else if (name != null)
+                               ns = Namespace.LookupNamespace (name, true);
+                       else
+                               ns = Namespace.Root;
+                       ns.AddNamespaceEntry (this);
+
+                       if ((parent != null) && (parent.NS != ns.Parent))
+                               implicit_parent = new NamespaceEntry (parent, file, ns.Parent.Name, true, loc);
+                       else
+                               implicit_parent = parent;
+
+                       this.FullName = ns.Name;
+               }
+
+               static int next_id = 0;
+               public readonly string FullName;
+               public readonly int ID;
+               public readonly bool IsImplicit;
+
+               public Namespace NS {
+                       get {
+                               return ns;
+                       }
+               }
+
+               public NamespaceEntry Parent {
+                       get {
+                               return parent;
+                       }
+               }
+
+               public NamespaceEntry ImplicitParent {
+                       get {
+                               return implicit_parent;
+                       }
+               }
+
+               public void DefineName (string name, IAlias o)
+               {
+                       ns.DefineName (name, o);
+               }
+
+               /// <summary>
+               ///   Records a new namespace for resolving name references
+               /// </summary>
+               public void Using (string ns, Location loc)
+               {
+                       if (DeclarationFound){
+                               Report.Error (1529, loc, "A using clause must precede all other namespace elements");
+                               return;
+                       }
+
+                       if (ns == FullName)
+                               return;
+                       
+                       if (using_clauses == null)
+                               using_clauses = new ArrayList ();
+
+                       foreach (UsingEntry old_entry in using_clauses) {
+                               if (old_entry.Name == ns) {
+                                       if (RootContext.WarningLevel >= 3)
+                                               Report.Warning (105, loc, "The using directive for '{0}' appeared previously in this namespace", ns);
+                                               return;
+                                       }
+                               }
+                       
+                       UsingEntry ue = new UsingEntry (this, ns, loc);
+                       using_clauses.Add (ue);
+               }
+
+               public void UsingAlias (string name, MemberName alias, Location loc)
+               {
+                       if (DeclarationFound){
+                               Report.Error (1529, loc, "A using clause must precede all other namespace elements");
+                               return;
+                       }
+
+                       if (aliases == null)
+                               aliases = new Hashtable ();
+
+                       if (aliases.Contains (name)){
+                               Report.Error (1537, loc, "The using alias `" + name +
+                                             "' appeared previously in this namespace");
+                               return;
+                       }
+
+                       aliases [name] = new AliasEntry (this, name, alias, loc);
+               }
+
+               protected AliasEntry GetAliasEntry (string alias)
+               {
+                       AliasEntry entry = null;
+
+                       if (aliases != null)
+                               entry = (AliasEntry) aliases [alias];
+                       if (entry == null && Parent != null)
+                               entry = Parent.GetAliasEntry (alias);
+
+                       return entry;
+               }
+
+               public IAlias LookupAlias (string alias)
+               {
+                       AliasEntry entry = GetAliasEntry (alias);
+
+                       if (entry == null)
+                               return null;
+
+                       return entry.Resolve ();
+               }
+
+               //
+               // According to section 16.3.1 (using-alias-directive), the namespace-or-type-name is 
+               // resolved as if the immediately containing namespace body has no using-directives.
+               //
+               // Section 16.3.2 says that the same rule is applied when resolving the namespace-name
+               // in the using-namespace-directive.
+               //
+               public IAlias LookupForUsing (string dotted_name, Location loc)
+               {
+                       int pos = dotted_name.IndexOf ('.');
+                       string simple_name = dotted_name;
+                       string rest = null;
+                       if (pos >= 0) {
+                               simple_name = dotted_name.Substring (0, pos);
+                               rest = dotted_name.Substring (pos + 1);
+                       }
+
+                       IAlias o = NS.Lookup (null, simple_name, loc);
+                       if (o == null && ImplicitParent != null)
+                               o = ImplicitParent.LookupNamespaceOrType (null, simple_name, loc);
+
+                       if (o == null || rest == null)
+                               return o;
+
+                       Namespace ns = o as Namespace;
+                       if (ns != null)
+                               return ns.Lookup (null, rest, loc);
+                       
+                       Type nested = TypeManager.LookupType (o.Name + "." + rest);
+                       if (nested == null)
+                               return null;
+
+                       return new TypeExpression (nested, loc);
+               }
+
+               public IAlias LookupNamespaceOrType (DeclSpace ds, string name, Location loc)
+               {
+                       IAlias resolved = null;
+                       for (NamespaceEntry curr_ns = this; curr_ns != null; curr_ns = curr_ns.ImplicitParent) {
+                               if ((resolved = curr_ns.Lookup (ds, name, loc)) != null)
+                                       break;
+                       }
+                       return resolved;
+               }
+
+               private IAlias Lookup (DeclSpace ds, string name, Location loc)
+               {
+                       IAlias o;
+                       Namespace ns;
+
+                       //
+                       // If name is of the form `N.I', first lookup `N', then search a member `I' in it.
+                       //
+                       // FIXME: Remove this block.  Only simple names should come here.
+                       //        The bug: The loop in LookupNamespaceOrType continues if 
+                       //        the lookup for N succeeds but the nested lookup for I fails.
+                       //        This is one part of #52697.
+                       //
+                       int pos = name.IndexOf ('.');
+                       if (pos >= 0) {
+                               string first = name.Substring (0, pos);
+                               string last = name.Substring (pos + 1);
+
+                               o = Lookup (ds, first, loc);
+                               if (o == null)
+                                       return null;
+
+                               ns = o as Namespace;
+                               if (ns != null) {
+                                       o = ns.Lookup (ds, last, loc);
+                                       return o;
+                               }
+
+                               Type nested = TypeManager.LookupType (o.Name + "." + last);
+                               if ((nested == null) || ((ds != null) && !ds.CheckAccessLevel (nested)))
+                                       return null;
+
+                               return new TypeExpression (nested, loc);
+                       }
+
+                       //
+                       // Check whether it's in the namespace.
+                       //
+                       o = NS.Lookup (ds, name, loc);
+                       if (o != null)
+                               return o;
+
+                       //
+                       // Check aliases.
+                       //
+                       AliasEntry entry = GetAliasEntry (name);
+                       if (entry != null) {
+                               IAlias alias = entry.Resolve ();
+                               if (alias != null)
+                                       return alias;
+                       }
+
+                       if (name.IndexOf ('.') > 0)
+                               return null;
+
+                       //
+                       // Check using entries.
+                       //
+                       IAlias t = null, match = null;
+                       foreach (Namespace using_ns in GetUsingTable ()) {
+                               match = using_ns.Lookup (ds, name, loc);
+                               if ((match != null) && match.IsType){
+                                       if (t != null) {
+                                                       DeclSpace.Error_AmbiguousTypeReference (loc, name, t.Name, match.Name);
+                                               return null;
+                                       } else {
+                                               t = match;
+                                       }
+                               }
+                       }
+
+                       return t;
+               }
+
+               // Our cached computation.
+               Namespace [] namespace_using_table;
+               public Namespace[] GetUsingTable ()
+               {
+                       if (namespace_using_table != null)
+                               return namespace_using_table;
+                       
+                       if (using_clauses == null)
+                               return new Namespace [0];
+
+                       ArrayList list = new ArrayList (using_clauses.Count);
+
+                       foreach (UsingEntry ue in using_clauses) {
+                               Namespace using_ns = ue.Resolve ();
+                               if (using_ns == null)
+                                       continue;
+
+                               list.Add (using_ns);
+                       }
+
+                       namespace_using_table = new Namespace [list.Count];
+                       list.CopyTo (namespace_using_table, 0);
+                       return namespace_using_table;
+               }
+
+               public void DefineNamespace (SymbolWriter symwriter)
+               {
+                       if (symfile_id != 0)
+                               return;
+                       if (parent != null)
+                               parent.DefineNamespace (symwriter);
+
+                       string[] using_list;
+                       if (using_clauses != null) {
+                               using_list = new string [using_clauses.Count];
+                               for (int i = 0; i < using_clauses.Count; i++)
+                                       using_list [i] = ((UsingEntry) using_clauses [i]).Name;
+                       } else {
+                               using_list = new string [0];
+                       }
+
+                       int parent_id = parent != null ? parent.symfile_id : 0;
+                       if (file.SourceFileEntry == null)
+                               return;
+
+                       symfile_id = symwriter.DefineNamespace (
+                               ns.Name, file.SourceFileEntry, using_list, parent_id);
+               }
+
+               public int SymbolFileID {
+                       get {
+                               return symfile_id;
+                       }
+               }
+
+               static void MsgtryRef (string s)
+               {
+                       Console.WriteLine ("    Try using -r:" + s);
+               }
+               
+               static void MsgtryPkg (string s)
+               {
+                       Console.WriteLine ("    Try using -pkg:" + s);
+               }
+
+               protected void error246 (Location loc, string name)
+               {
+                       Report.Error (246, loc, "The namespace `" + name +
+                                     "' can not be found (missing assembly reference?)");
+
+                       switch (name) {
+                       case "Gtk": case "GtkSharp":
+                               MsgtryPkg ("gtk-sharp");
+                               break;
+
+                       case "Gdk": case "GdkSharp":
+                               MsgtryPkg ("gdk-sharp");
+                               break;
+
+                       case "Glade": case "GladeSharp":
+                               MsgtryPkg ("glade-sharp");
+                               break;
+
+                       case "System.Drawing":
+                       case "System.Web.Services":
+                       case "System.Web":
+                       case "System.Data":
+                       case "System.Windows.Forms":
+                               MsgtryRef (name);
+                               break;
+                       }
+               }
+
+               /// <summary>
+               ///   Used to validate that all the using clauses are correct
+               ///   after we are finished parsing all the files.  
+               /// </summary>
+               public void VerifyUsing ()
+               {
+                       TypeContainer dummy = new RootTypes ();
+                       EmitContext ec = new EmitContext (
+                               dummy, Location.Null, null, null, 0, false);
+
+                       if (using_clauses != null){
+                               foreach (UsingEntry ue in using_clauses){
+                                       if (ue.Resolve () != null)
+                                               continue;
+
+                                       if (LookupForUsing (ue.Name, ue.Location) == null)
+                                               error246 (ue.Location, ue.Name);
+                                       else
+                                               Report.Error (138, ue.Location, "The using keyword only lets you specify a namespace, " +
+                                                             "`" + ue.Name + "' is a class not a namespace.");
+
+                               }
+                       }
+
+                       if (aliases != null){
+                               foreach (DictionaryEntry de in aliases){
+                                       AliasEntry entry = (AliasEntry) de.Value;
+
+                                       IAlias alias = entry.Resolve ();
+                                       if (alias != null) {
+                                               if (alias.IsType)
+                                                       alias.ResolveAsType (ec);
+
+                                               continue;
+                                       }
+
+                                       error246 (entry.Location, entry.Alias.GetTypeName ());
+                               }
+                       }
+               }
+
+               public override string ToString ()
+               {
+                       if (NS == Namespace.Root)
+                               return "NamespaceEntry (<root>)";
+                       else
+                               return String.Format ("NamespaceEntry ({0},{1},{2})", FullName, IsImplicit, ID);
+               }
+       }
+}
diff --git a/mcs/bmcs/parameter.cs b/mcs/bmcs/parameter.cs
new file mode 100644 (file)
index 0000000..17523ac
--- /dev/null
@@ -0,0 +1,703 @@
+//
+// parameter.cs: Parameter definition.
+//
+// Author: Miguel de Icaza (miguel@gnu.org)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+//
+//
+//
+using System;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Collections;
+
+namespace Mono.CSharp {
+
+       /// <summary>
+       ///   Abstract Base class for parameters of a method.
+       /// </summary>
+       public abstract class ParameterBase : Attributable {
+
+               protected ParameterBuilder builder;
+
+               public ParameterBase (Attributes attrs)
+                       : base (attrs)
+               {
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type == TypeManager.marshal_as_attr_type) {
+                               UnmanagedMarshal marshal = a.GetMarshal (this);
+                               if (marshal != null) {
+                                       builder.SetMarshal (marshal);
+                               }
+                                       return;
+                       }
+
+                       if (a.Type.IsSubclassOf (TypeManager.security_attr_type)) {
+                               a.Error_InvalidSecurityParent ();
+                               return;
+                       }
+
+                       builder.SetCustomAttribute (cb);
+               }
+
+               public override bool IsClsCompliaceRequired(DeclSpace ds)
+               {
+                       return false;
+                               }
+       }
+
+       /// <summary>
+       /// Class for applying custom attributes on the return type
+       /// </summary>
+       public class ReturnParameter: ParameterBase {
+               public ReturnParameter (MethodBuilder mb, Location location):
+                       base (null)
+               {
+                       try {
+                               builder = mb.DefineParameter (0, ParameterAttributes.None, "");                 
+                       }
+                       catch (ArgumentOutOfRangeException) {
+                               Report.Warning (-28, location, "The Microsoft .NET Runtime 1.x does not permit setting custom attributes on the return type");
+                       }
+               }
+
+               public override void ApplyAttributeBuilder(Attribute a, CustomAttributeBuilder cb)
+               {
+                       // This occurs after Warning -28
+                       if (builder == null)
+                               return;
+
+                       base.ApplyAttributeBuilder (a, cb);
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.ReturnValue;
+                       }
+               }
+
+               /// <summary>
+               /// Is never called
+               /// </summary>
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return null;
+                       }
+               }
+       }
+
+       /// <summary>
+       /// Class for applying custom attributes on the implicit parameter type
+       /// of the 'set' method in properties, and the 'add' and 'remove' methods in events.
+       /// </summary>
+       public class ImplicitParameter: ParameterBase {
+               public ImplicitParameter (MethodBuilder mb):
+                       base (null)
+               {
+                       builder = mb.DefineParameter (1, ParameterAttributes.None, "");                 
+               }
+
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Parameter;
+                       }
+               }
+
+               /// <summary>
+               /// Is never called
+               /// </summary>
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return null;
+                       }
+       }
+       }
+
+
+       /// <summary>
+       ///   Represents a single method parameter
+       /// </summary>
+
+       //TODO: Add location member to this or base class for better error location and all methods simplification.
+       public class Parameter : ParameterBase {
+               [Flags]
+               public enum Modifier : byte {
+                       NONE    = 0,
+                       VAL     = 0,
+                       REF     = 1,
+                       OUT     = 2,
+                       PARAMS  = 4,
+                       // This is a flag which says that it's either REF or OUT.
+                       ISBYREF = 8,
+                       ARGLIST = 16,
+                       // This value is changed from the one in mbas source code
+                       OPTIONAL = 32
+               }
+
+               static string[] attribute_targets = new string [] { "param" };
+
+               public Expression TypeName;
+               public readonly Modifier ModFlags;
+               public readonly string Name;
+               GenericConstraints constraints;
+               Type parameter_type;
+
+               /* These two fields are mbas specific. The corresponding 
+               changes need to be merged from mbas */
+               
+               public readonly Expression ParameterInitializer;
+               public readonly bool IsOptional;
+               
+               public Parameter (Expression type, string name, Modifier mod, Attributes attrs)
+                       : base (attrs)
+               {
+                       Name = name;
+                       ModFlags = mod;
+                       TypeName = type;
+                       ParameterInitializer = null;
+                       IsOptional = false;
+               }
+
+               public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Expression pi)
+                       : base (attrs)
+               {
+                       Name = name;
+                       ModFlags = mod;
+                       TypeName = type;
+                       ParameterInitializer = pi;
+                       IsOptional = false;
+               }
+
+               public Parameter (Expression type, string name, Modifier mod, Attributes attrs, Expression pi, bool opt)
+                       : base (attrs)
+               {
+                       Name = name;
+                       ModFlags = mod;
+                       TypeName = type;
+                       ParameterInitializer = pi;
+                       IsOptional = opt;
+               }
+
+               public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb)
+               {
+                       if (a.Type == TypeManager.param_array_type) {
+                               Report.Error (674, a.Location, "Do not use 'System.ParamArrayAttribute'. Use the 'params' keyword instead");
+                               return;
+                       }
+                       base.ApplyAttributeBuilder (a, cb);
+               }
+
+               // <summary>
+               //   Resolve is used in method definitions
+               // </summary>
+               public bool Resolve (EmitContext ec, Location l)
+               {
+                       TypeExpr texpr = TypeName.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return false;
+
+                       TypeParameterExpr tparam = texpr as TypeParameterExpr;
+                       if (tparam != null)
+                               constraints = tparam.TypeParameter.Constraints;
+
+                       parameter_type = texpr.Type;
+
+                       if (parameter_type.IsAbstract && parameter_type.IsSealed) {
+                               Report.Error (721, l, "'{0}': static types cannot be used as parameters", GetSignatureForError ());
+                               return false;
+                       }
+
+                       if (parameter_type == TypeManager.void_type){
+                               Report.Error (1536, l, "`void' parameter is not permitted");
+                               return false;
+                       }
+
+                       if ((ModFlags & Parameter.Modifier.ISBYREF) != 0){
+                               if (parameter_type == TypeManager.typed_reference_type ||
+                                   parameter_type == TypeManager.arg_iterator_type){
+                                       Report.Error (1601, l,
+                                                     "out or ref parameter can not be of type TypedReference or ArgIterator");
+                                       return false;
+                               }
+                       }
+                       
+                       return parameter_type != null;
+               }
+
+               public Type ExternalType ()
+               {
+                       if ((ModFlags & Parameter.Modifier.ISBYREF) != 0)
+                               return TypeManager.GetReferenceType (parameter_type);
+                       
+                       return parameter_type;
+               }
+
+               public Type ParameterType {
+                       get {
+                               return parameter_type;
+                       }
+               }
+
+               public GenericConstraints GenericConstraints {
+                       get {
+                               return constraints;
+                       }
+               }
+               
+               public ParameterAttributes Attributes {
+                       get {
+                               int flags = ((int) ModFlags) & ~((int) Parameter.Modifier.ISBYREF);
+                               switch ((Modifier) flags) {
+                               case Modifier.NONE:
+                                       return ParameterAttributes.None;
+                               case Modifier.REF:
+                                       return ParameterAttributes.None;
+                               case Modifier.OUT:
+                                       return ParameterAttributes.Out;
+                               case Modifier.PARAMS:
+                                       return 0;
+                               }
+                               
+                               return ParameterAttributes.None;
+                       }
+               }
+
+               public static ParameterAttributes GetParameterAttributes (Modifier mod)
+               {
+                       int flags = ((int) mod) & ~((int) Parameter.Modifier.ISBYREF);
+                       switch ((Modifier) flags) {
+                       case Modifier.NONE:
+                               return ParameterAttributes.None;
+                       case Modifier.REF:
+                               return ParameterAttributes.None;
+                       case Modifier.OUT:
+                               return ParameterAttributes.Out;
+                       case Modifier.PARAMS:
+                               return 0;
+                       }
+                               
+                       return ParameterAttributes.None;
+               }
+               
+               public override AttributeTargets AttributeTargets {
+                       get {
+                               return AttributeTargets.Parameter;
+                       }
+               }
+
+               /// <summary>
+               ///   Returns the signature for this parameter evaluating it on the
+               ///   @tc context
+               /// </summary>
+               public string GetSignature (EmitContext ec, Location loc)
+               {
+                       if (parameter_type == null){
+                               if (!Resolve (ec, loc))
+                                       return null;
+                       }
+
+                       return ExternalType ().FullName;
+               }
+
+               public string GetSignatureForError ()
+               {
+                       string typeName;
+                       if (parameter_type != null)
+                               typeName = TypeManager.CSharpName (parameter_type);
+                       else if (TypeName.Type != null)
+                               typeName = TypeManager.CSharpName (TypeName.Type);
+                       else
+                               typeName = TypeName.ToString ();
+
+                       switch (ModFlags & unchecked (~Modifier.ISBYREF)) {
+                               case Modifier.OUT:
+                                       return "out " + typeName;
+                               case Modifier.PARAMS:
+                                       return "params " + typeName;
+                               case Modifier.REF:
+                                       return "ref " + typeName;
+                       }
+                       return typeName;
+               }
+
+               public void DefineParameter (EmitContext ec, MethodBuilder mb, ConstructorBuilder cb, int index, Location loc)
+               {
+                       ParameterAttributes par_attr = Attributes;
+                                       
+                       if (mb == null)
+                               builder = cb.DefineParameter (index, par_attr, Name);
+                       else 
+                               builder = mb.DefineParameter (index, par_attr, Name);
+                                       
+                       if (OptAttributes != null) {
+                               OptAttributes.Emit (ec, this);
+       
+                               if (par_attr == ParameterAttributes.Out){
+                                       if (OptAttributes.Contains (TypeManager.in_attribute_type, ec))
+                                               Report.Error (36, loc,  "Can not use [In] attribute on out parameter");
+                               }
+                       }
+               }
+
+               public override string[] ValidAttributeTargets {
+                       get {
+                               return attribute_targets;
+                       }
+               }
+               
+       }
+
+       /// <summary>
+       ///   Represents the methods parameters
+       /// </summary>
+       public class Parameters {
+               public Parameter [] FixedParameters;
+               public readonly Parameter ArrayParameter;
+               public readonly bool HasArglist;
+               string signature;
+               Type [] types;
+               Location loc;
+               
+               static Parameters empty_parameters;
+               
+               public Parameters (Parameter [] fixed_parameters, Parameter array_parameter, Location l)
+               {
+                       FixedParameters = fixed_parameters;
+                       ArrayParameter  = array_parameter;
+                       loc = l;
+               }
+
+               public Parameters (Parameter [] fixed_parameters, bool has_arglist, Location l)
+               {
+                       FixedParameters = fixed_parameters;
+                       HasArglist = has_arglist;
+                       loc = l;
+               }
+
+               /// <summary>
+               ///   This is used to reuse a set of empty parameters, because they
+               ///   are common
+               /// </summary>
+               public static Parameters EmptyReadOnlyParameters {
+                       get {
+                               if (empty_parameters == null)
+                                       empty_parameters = new Parameters (null, null, Location.Null);
+                       
+                               return empty_parameters;
+                       }
+               }
+               
+               public bool Empty {
+                       get {
+                               return (FixedParameters == null) && (ArrayParameter == null);
+                       }
+               }
+               
+               public void ComputeSignature (EmitContext ec)
+               {
+                       signature = "";
+                       if (FixedParameters != null){
+                               for (int i = 0; i < FixedParameters.Length; i++){
+                                       Parameter par = FixedParameters [i];
+                                       
+                                       signature += par.GetSignature (ec, loc);
+                               }
+                       }
+                       //
+                       // Note: as per the spec, the `params' arguments (ArrayParameter)
+                       // are not used in the signature computation for a method
+                       //
+
+               }
+
+               void Error_DuplicateParameterName (string name)
+               {
+                       Report.Error (
+                               100, loc, "The parameter name `" + name + "' is a duplicate");
+               }
+               
+               public bool VerifyArgs ()
+               {
+                       int count;
+                       int i, j;
+
+                       if (FixedParameters == null)
+                               return true;
+                       
+                       count = FixedParameters.Length;
+                       string array_par_name = ArrayParameter != null ? ArrayParameter.Name : null;
+
+                       for (i = 0; i < count; i++){
+                               string base_name = FixedParameters [i].Name;
+                               for (j = i + 1; j < count; j++){
+                                       if (base_name != FixedParameters [j].Name)
+                                               continue;
+                                       Error_DuplicateParameterName (base_name);
+                                       return false;
+                               }
+
+                               if (base_name == array_par_name){
+                                       Error_DuplicateParameterName (base_name);
+                                       return false;
+                               }
+                       }
+                       return true;
+               }
+               
+               /// <summary>
+               ///    Returns the signature of the Parameters evaluated in
+               ///    the @ec EmitContext
+               /// </summary>
+               public string GetSignature (EmitContext ec)
+               {
+                       if (signature == null){
+                               VerifyArgs ();
+                               ComputeSignature (ec);
+                       }
+                       
+                       return signature;
+               }
+               
+               /// <summary>
+               ///    Returns the paramenter information based on the name
+               /// </summary>
+               public Parameter GetParameterByName (string name, out int idx)
+               {
+                       idx = 0;
+                       int i = 0;
+
+                       if (FixedParameters != null){
+                               foreach (Parameter par in FixedParameters){
+                                       if (par.Name == name){
+                                               idx = i;
+                                               return par;
+                                       }
+                                       i++;
+                               }
+                       }
+
+                       if (ArrayParameter != null){
+                               if (name == ArrayParameter.Name){
+                                       idx = i;
+                                       return ArrayParameter;
+                               }
+                       }
+                       
+                       return null;
+               }
+
+               public Parameter GetParameterByName (string name)
+               {
+                       int idx;
+
+                       return GetParameterByName (name, out idx);
+               }
+               
+               bool ComputeParameterTypes (EmitContext ec)
+               {
+                       int extra = (ArrayParameter != null) ? 1 : 0;
+                       int i = 0;
+                       int pc;
+
+                       if (FixedParameters == null)
+                               pc = extra;
+                       else
+                               pc = extra + FixedParameters.Length;
+
+                       types = new Type [pc];
+                       
+                       if (!VerifyArgs ()){
+                               FixedParameters = null;
+                               return false;
+                       }
+
+                       bool failed = false;
+                       if (FixedParameters != null){
+                               foreach (Parameter p in FixedParameters){
+                                       Type t = null;
+                                       
+                                       if (p.Resolve (ec, loc))
+                                               t = p.ExternalType ();
+                                       else
+                                               failed = true;
+
+                                       types [i] = t;
+                                       i++;
+
+                               }
+                       }
+                       
+                       if (extra > 0){
+                               if (ArrayParameter.Resolve (ec, loc))
+                                       types [i] = ArrayParameter.ExternalType ();
+                               else 
+                                       failed = true;
+                       }
+
+                       if (failed){
+                               types = null;
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               //
+               // This variant is used by Delegates, because they need to
+               // resolve/define names, instead of the plain LookupType
+               //
+               public bool ComputeAndDefineParameterTypes (EmitContext ec)
+               {
+                       bool old_type_resolving = ec.ResolvingTypeTree;
+                       ec.ResolvingTypeTree = true;
+                       bool retval = ComputeParameterTypes (ec);
+                       ec.ResolvingTypeTree = old_type_resolving;
+                       return retval;
+               }
+               
+               /// <summary>
+               ///   Returns the argument types as an array
+               /// </summary>
+               static Type [] no_types = new Type [0];
+               
+               public Type [] GetParameterInfo (EmitContext ec)
+               {
+                       if (types != null)
+                               return types;
+                       
+                       if (FixedParameters == null && ArrayParameter == null)
+                               return no_types;
+
+                       if (ComputeParameterTypes (ec) == false){
+                               types = null;
+                               return null;
+                       }
+
+                       return types;
+               }
+
+               /// <summary>
+               ///   Returns the type of a given parameter, and stores in the `is_out'
+               ///   boolean whether this is an out or ref parameter.
+               ///
+               ///   Note that the returned type will not contain any dereference in this
+               ///   case (ie, you get "int" for a ref int instead of "int&"
+               /// </summary>
+               public Type GetParameterInfo (EmitContext ec, int idx, out Parameter.Modifier mod)
+               {
+                       mod = Parameter.Modifier.NONE;
+                       
+                       if (!VerifyArgs ()){
+                               FixedParameters = null;
+                               return null;
+                       }
+
+                       if (FixedParameters == null && ArrayParameter == null)
+                               return null;
+                       
+                       if (types == null)
+                               if (ComputeParameterTypes (ec) == false)
+                                       return null;
+
+                       //
+                       // If this is a request for the variable lenght arg.
+                       //
+                       int array_idx = (FixedParameters != null ? FixedParameters.Length : 0);
+                       if (idx == array_idx)
+                               return types [idx];
+
+                       //
+                       // Otherwise, it is a fixed parameter
+                       //
+                       Parameter p = FixedParameters [idx];
+                       mod = p.ModFlags;
+
+                       if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0)
+                               mod |= Parameter.Modifier.ISBYREF;
+
+                       return p.ParameterType;
+               }
+
+               public CallingConventions GetCallingConvention ()
+               {
+                       if (HasArglist)
+                               return CallingConventions.VarArgs;
+                       else
+                       return CallingConventions.Standard;
+               }
+
+               //
+               // The method's attributes are passed in because we need to extract
+               // the "return:" attribute from there to apply on the return type
+               //
+               public void LabelParameters (EmitContext ec,
+                       MethodBase builder,
+                       Location loc) {
+                       //
+                       // Define each type attribute (in/out/ref) and
+                       // the argument names.
+                       //
+                       int i = 0;
+                       
+                       MethodBuilder mb = builder as MethodBuilder;
+                       ConstructorBuilder cb = builder as ConstructorBuilder;
+
+                       if (FixedParameters != null) {
+                               for (i = 0; i < FixedParameters.Length; i++) {
+                                       FixedParameters [i].DefineParameter (ec, mb, cb, i + 1, loc);
+                               }
+                       }
+
+                       if (ArrayParameter != null){
+                               ParameterBuilder pb;
+                               Parameter array_param = ArrayParameter;
+
+                               if (mb == null)
+                                       pb = cb.DefineParameter (
+                                               i + 1, array_param.Attributes,
+                                               array_param.Name);
+                               else
+                                       pb = mb.DefineParameter (
+                                               i + 1, array_param.Attributes,
+                                               array_param.Name);
+                                       
+                               CustomAttributeBuilder a = new CustomAttributeBuilder (
+                                       TypeManager.cons_param_array_attribute, new object [0]);
+                               
+                               pb.SetCustomAttribute (a);
+                       }
+               }
+
+               public Parameters Copy (Location l)
+               {
+                       Parameters p = new Parameters (null, null, l);
+                       p.FixedParameters = new Parameter[this.FixedParameters.Length];
+                       this.FixedParameters.CopyTo (p.FixedParameters, 0);
+               
+                       return (p);
+               }
+
+               public void AppendParameter (Parameter p)
+               {
+                       if (FixedParameters != null) 
+                       {
+                               Parameter [] pa = new Parameter [FixedParameters.Length+1];
+                               FixedParameters.CopyTo (pa, 0);
+                               pa[FixedParameters.Length] = p;
+                               FixedParameters = pa;           
+                       }
+                       else
+                       {
+                               FixedParameters = new Parameter [1];
+                               FixedParameters[0] = p;
+                       }
+
+               }
+       }
+}
diff --git a/mcs/bmcs/parser.cs b/mcs/bmcs/parser.cs
new file mode 100644 (file)
index 0000000..2750724
--- /dev/null
@@ -0,0 +1,23 @@
+
+namespace Compiler {
+
+       using System;
+
+       abstract public class Parser {
+               public string name;
+               public System.IO.Stream input;
+               
+               public Parser (Mono.CSharp.Tree tree, string name, System.IO.Stream stream) 
+               {
+                       this.tree = tree;
+                       this.name = name;
+                       this.input = stream;
+               }
+
+               public string getName (){
+                       return name;
+               }
+
+               abstract public int parse ();
+       }
+}
diff --git a/mcs/bmcs/pending.cs b/mcs/bmcs/pending.cs
new file mode 100644 (file)
index 0000000..550904b
--- /dev/null
@@ -0,0 +1,582 @@
+//
+// pending.cs: Pending method implementation
+//
+// Author:
+//   Miguel de Icaza (miguel@gnu.org)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001, 2002 Ximian, Inc (http://www.ximian.com)
+//
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace Mono.CSharp {
+
+       struct TypeAndMethods {
+               public Type          type;
+               public MethodInfo [] methods;
+
+               // 
+               // Whether it is optional, this is used to allow the explicit/implicit
+               // implementation when a parent class already implements an interface. 
+               //
+               // For example:
+               //
+               // class X : IA { }  class Y : X, IA { IA.Explicit (); }
+               //
+               public bool          optional;
+               
+               // Far from ideal, but we want to avoid creating a copy
+               // of methods above.
+               public Type [][]     args;
+
+               //
+               // This flag on the method says `We found a match, but
+               // because it was private, we could not use the match
+               //
+               public bool []       found;
+
+               // If a method is defined here, then we always need to
+               // create a proxy for it.  This is used when implementing
+               // an interface's indexer with a different IndexerName.
+               public MethodInfo [] need_proxy;
+
+               //
+               // The name of the indexer (if it exists), precompute set/get, because
+               // they would be recomputed many times inside a loop later on.
+               //
+               public string set_indexer_name;
+               public string get_indexer_name;
+       }
+
+       public class PendingImplementation {
+               /// <summary>
+               ///   The container for this PendingImplementation
+               /// </summary>
+               TypeContainer container;
+               
+               /// <summary>
+               ///   This filter is used by FindMembers, and it is used to
+               ///   extract only virtual/abstract fields
+               /// </summary>
+               static MemberFilter virtual_method_filter;
+
+               /// <summary>
+               ///   This is the array of TypeAndMethods that describes the pending implementations
+               ///   (both interfaces and abstract methods in parent class)
+               /// </summary>
+               TypeAndMethods [] pending_implementations;
+
+               static bool IsVirtualFilter (MemberInfo m, object filterCriteria)
+               {
+                       MethodInfo mi = m as MethodInfo;
+                       return (mi == null) ? false : mi.IsVirtual;
+               }
+
+               /// <summary>
+               ///   Inits the virtual_method_filter
+               /// </summary>
+               static PendingImplementation ()
+               {
+                       virtual_method_filter = new MemberFilter (IsVirtualFilter);
+               }
+
+               // <remarks>
+               //   Returns a list of the abstract methods that are exposed by all of our
+               //   parents that we must implement.  Notice that this `flattens' the
+               //   method search space, and takes into account overrides.  
+               // </remarks>
+               static ArrayList GetAbstractMethods (Type t)
+               {
+                       ArrayList list = null;
+                       bool searching = true;
+                       Type current_type = t;
+                       
+                       do {
+                               MemberList mi;
+                               
+                               mi = TypeContainer.FindMembers (
+                                       current_type, MemberTypes.Method,
+                                       BindingFlags.Public | BindingFlags.Instance |
+                                       BindingFlags.DeclaredOnly,
+                                       virtual_method_filter, null);
+
+                               if (current_type == TypeManager.object_type)
+                                       searching = false;
+                               else {
+                                       current_type = current_type.BaseType;
+                                       if (!current_type.IsAbstract)
+                                               searching = false;
+                               }
+
+                               if (mi.Count == 0)
+                                       continue;
+
+                               if (mi.Count == 1 && !(mi [0] is MethodBase))
+                                       searching = false;
+                               else 
+                                       list = TypeManager.CopyNewMethods (list, mi);
+                       } while (searching);
+
+                       if (list == null)
+                               return null;
+                       
+                       for (int i = 0; i < list.Count; i++){
+                               while (list.Count > i && !((MethodInfo) list [i]).IsAbstract)
+                                       list.RemoveAt (i);
+                       }
+
+                       if (list.Count == 0)
+                               return null;
+
+                       return list;
+               }
+
+               PendingImplementation (TypeContainer container, MissingInterfacesInfo [] missing_ifaces, ArrayList abstract_methods, int total)
+               {
+                       TypeBuilder type_builder = container.TypeBuilder;
+                       
+                       this.container = container;
+                       pending_implementations = new TypeAndMethods [total];
+
+                       int i = 0;
+                       foreach (MissingInterfacesInfo missing in missing_ifaces){
+                               MethodInfo [] mi;
+                               Type t = missing.Type;
+                               
+                               if (!t.IsInterface)
+                                       continue;
+
+                               if (t is TypeBuilder){
+                                       TypeContainer iface;
+
+                                       iface = TypeManager.LookupInterface (t);
+                                       
+                                       mi = iface.GetMethods ();
+                               } else 
+                                       mi = t.GetMethods ();
+                               
+                               int count = mi.Length;
+                               pending_implementations [i].type = t;
+                               pending_implementations [i].optional = missing.Optional;
+                               pending_implementations [i].methods = mi;
+                               pending_implementations [i].args = new Type [count][];
+                               pending_implementations [i].found = new bool [count];
+                               pending_implementations [i].need_proxy = new MethodInfo [count];
+                               string indexer_name = TypeManager.IndexerPropertyName (t);
+
+                               pending_implementations [i].set_indexer_name = "set_" + indexer_name;
+                               pending_implementations [i].get_indexer_name = "get_" + indexer_name;
+                               
+                               int j = 0;
+                               foreach (MethodInfo m in mi){
+                                       Type [] types = TypeManager.GetArgumentTypes (m);
+                                       
+                                       pending_implementations [i].args [j] = types;
+                                       j++;
+                               }
+                               i++;
+                       }
+
+                       if (abstract_methods != null){
+                               int count = abstract_methods.Count;
+                               pending_implementations [i].methods = new MethodInfo [count];
+                               pending_implementations [i].need_proxy = new MethodInfo [count];
+                               
+                               abstract_methods.CopyTo (pending_implementations [i].methods, 0);
+                               pending_implementations [i].found = new bool [count];
+                               pending_implementations [i].args = new Type [count][];
+                               pending_implementations [i].type = type_builder;
+
+                               string indexer_name = TypeManager.IndexerPropertyName (type_builder);
+                               pending_implementations [i].set_indexer_name = "set_" + indexer_name;
+                               pending_implementations [i].get_indexer_name = "get_" + indexer_name;
+                               
+                               int j = 0;
+                               foreach (MemberInfo m in abstract_methods){
+                                       MethodInfo mi = (MethodInfo) m;
+                                       
+                                       Type [] types = TypeManager.GetArgumentTypes (mi);
+                                       
+                                       pending_implementations [i].args [j] = types;
+                                       j++;
+                               }
+                       }
+               }
+
+               struct MissingInterfacesInfo {
+                       public Type Type;
+                       public bool Optional;
+
+                       public MissingInterfacesInfo (Type t)
+                       {
+                               Type = t;
+                               Optional = false;
+                       }
+               }
+
+               static MissingInterfacesInfo [] EmptyMissingInterfacesInfo = new MissingInterfacesInfo [0];
+               
+               static MissingInterfacesInfo [] GetMissingInterfaces (TypeBuilder type_builder)
+               {
+                       //
+                       // Notice that TypeBuilders will only return the interfaces that the Type
+                       // is supposed to implement, not all the interfaces that the type implements.
+                       //
+                       // Even better -- on MS it returns an empty array, no matter what.
+                       //
+                       // Completely broken.  So we do it ourselves!
+                       //
+                       Type [] impl = TypeManager.GetExplicitInterfaces (type_builder);
+
+                       if (impl == null || impl.Length == 0)
+                               return EmptyMissingInterfacesInfo;
+
+                       MissingInterfacesInfo [] ret = new MissingInterfacesInfo [impl.Length];
+
+                       for (int i = 0; i < impl.Length; i++)
+                               ret [i] = new MissingInterfacesInfo (impl [i]);
+
+                       // we really should not get here because Object doesnt implement any
+                       // interfaces. But it could implement something internal, so we have
+                       // to handle that case.
+                       if (type_builder.BaseType == null)
+                               return ret;
+                       
+                       Type [] parent_impls = TypeManager.GetInterfaces (type_builder.BaseType);
+                       
+                       foreach (Type t in parent_impls) {
+                               for (int i = 0; i < ret.Length; i ++) {
+                                       if (t == ret [i].Type) {
+                                               ret [i].Optional = true;
+                                               break;
+                                       }
+                               }
+                       }
+                       return ret;
+               }
+               
+               //
+               // Factory method: if there are pending implementation methods, we return a PendingImplementation
+               // object, otherwise we return null.
+               //
+               // Register method implementations are either abstract methods
+               // flagged as such on the base class or interface methods
+               //
+               static public PendingImplementation GetPendingImplementations (TypeContainer container)
+               {
+                       TypeBuilder type_builder = container.TypeBuilder;
+                       MissingInterfacesInfo [] missing_interfaces;
+                       Type b = type_builder.BaseType;
+
+                       missing_interfaces = GetMissingInterfaces (type_builder);
+
+                       //
+                       // If we are implementing an abstract class, and we are not
+                       // ourselves abstract, and there are abstract methods (C# allows
+                       // abstract classes that have no abstract methods), then allocate
+                       // one slot.
+                       //
+                       // We also pre-compute the methods.
+                       //
+                       bool implementing_abstract = ((b != null) && b.IsAbstract && !type_builder.IsAbstract);
+                       ArrayList abstract_methods = null;
+
+                       if (implementing_abstract){
+                               abstract_methods = GetAbstractMethods (b);
+                               
+                               if (abstract_methods == null)
+                                       implementing_abstract = false;
+                       }
+                       
+                       int total = missing_interfaces.Length +  (implementing_abstract ? 1 : 0);
+                       if (total == 0)
+                               return null;
+
+                       return new PendingImplementation (container, missing_interfaces, abstract_methods, total);
+               }
+
+               public enum Operation {
+                       //
+                       // If you change this, review the whole InterfaceMethod routine as there
+                       // are a couple of assumptions on these three states
+                       //
+                       Lookup, ClearOne, ClearAll
+               }
+
+               /// <summary>
+               ///   Whether the specified method is an interface method implementation
+               /// </summary>
+               public MethodInfo IsInterfaceMethod (Type t, string name, Type ret_type, Type [] args)
+               {
+                       return InterfaceMethod (t, name, ret_type, args, Operation.Lookup, null);
+               }
+
+               public MethodInfo IsInterfaceIndexer (Type t, Type ret_type, Type [] args)
+               {
+                       return InterfaceMethod (t, null, ret_type, args, Operation.Lookup, null);
+               }
+
+               public void ImplementMethod (Type t, string name, Type ret_type, Type [] args, bool clear_one) 
+               {
+                       InterfaceMethod (t, name, ret_type, args,
+                                        clear_one ? Operation.ClearOne : Operation.ClearAll, null);
+               }
+
+               public void ImplementIndexer (Type t, MethodInfo mi, Type ret_type, Type [] args, bool clear_one) 
+               {
+                       InterfaceMethod (t, null, ret_type, args,
+                                        clear_one ? Operation.ClearOne : Operation.ClearAll, mi);
+               }
+               
+               /// <remarks>
+               ///   If a method in Type `t' (or null to look in all interfaces
+               ///   and the base abstract class) with name `Name', return type `ret_type' and
+               ///   arguments `args' implements an interface, this method will
+               ///   return the MethodInfo that this method implements.
+               ///
+               ///   If `name' is null, we operate solely on the method's signature.  This is for
+               ///   instance used when implementing indexers.
+               ///
+               ///   The `Operation op' controls whether to lookup, clear the pending bit, or clear
+               ///   all the methods with the given signature.
+               ///
+               ///   The `MethodInfo need_proxy' is used when we're implementing an interface's
+               ///   indexer in a class.  If the new indexer's IndexerName does not match the one
+               ///   that was used in the interface, then we always need to create a proxy for it.
+               ///
+               /// </remarks>
+               public MethodInfo InterfaceMethod (Type t, string name, Type ret_type, Type [] args,
+                                                  Operation op, MethodInfo need_proxy)
+               {
+                       int arg_len = args.Length;
+
+                       if (pending_implementations == null)
+                               return null;
+
+                       foreach (TypeAndMethods tm in pending_implementations){
+                               if (!(t == null || tm.type == t))
+                                       continue;
+
+                               int method_count = tm.methods.Length;
+                               MethodInfo m;
+                               for (int i = 0; i < method_count; i++){
+                                       m = tm.methods [i];
+
+                                       if (m == null)
+                                               continue;
+
+                                       string mname = TypeManager.GetMethodName (m);
+
+                                       //
+                                       // `need_proxy' is not null when we're implementing an
+                                       // interface indexer and this is Clear(One/All) operation.
+                                       //
+                                       // If `name' is null, then we do a match solely based on the
+                                       // signature and not on the name (this is done in the Lookup
+                                       // for an interface indexer).
+                                       //
+                                       if (name == null){
+                                               if (mname != tm.get_indexer_name && mname != tm.set_indexer_name)
+                                                       continue;
+                                       } else if ((need_proxy == null) && (name != mname))
+                                               continue;
+
+                                       if (!TypeManager.IsEqual (ret_type, m.ReturnType)){
+                                               if (!((ret_type == null && m.ReturnType == TypeManager.void_type) ||
+                                                     (m.ReturnType == null && ret_type == TypeManager.void_type)))
+                                                       continue;
+                                       }
+
+                                       //
+                                       // Check if we have the same parameters
+                                       //
+                                       if (tm.args [i].Length != arg_len)
+                                               continue;
+
+                                       int j, top = args.Length;
+                                       bool fail = false;
+
+                                       for (j = 0; j < top; j++){
+                                               if (!TypeManager.IsEqual (tm.args [i][j], args[j])){
+                                                       fail = true;
+                                                       break;
+                                               }
+                                       }
+                                       if (fail)
+                                               continue;
+
+                                       if (op != Operation.Lookup){
+                                               // If `t != null', then this is an explicitly interface
+                                               // implementation and we can always clear the method.
+                                               // `need_proxy' is not null if we're implementing an
+                                               // interface indexer.  In this case, we need to create
+                                               // a proxy if the implementation's IndexerName doesn't
+                                               // match the IndexerName in the interface.
+                                               bool name_matches = false;
+                                               if (name == mname || mname == tm.get_indexer_name || mname == tm.set_indexer_name)
+                                                       name_matches = true;
+                                               
+                                               if ((t == null) && (need_proxy != null) && !name_matches)
+                                                       tm.need_proxy [i] = need_proxy;
+                                               else 
+                                                       tm.methods [i] = null;
+                                       }
+                                       tm.found [i] = true;
+
+                                       //
+                                       // Lookups and ClearOne return
+                                       //
+                                       if (op != Operation.ClearAll)
+                                               return m;
+                               }
+
+                               // If a specific type was requested, we can stop now.
+                               if (tm.type == t)
+                                       return null;
+                       }
+                       return null;
+               }
+
+               /// <summary>
+               ///   C# allows this kind of scenarios:
+               ///   interface I { void M (); }
+               ///   class X { public void M (); }
+               ///   class Y : X, I { }
+               ///
+               ///   For that case, we create an explicit implementation function
+               ///   I.M in Y.
+               /// </summary>
+               void DefineProxy (Type iface, MethodInfo parent_method, MethodInfo iface_method,
+                                 Type [] args)
+               {
+                       MethodBuilder proxy;
+
+                       string proxy_name = iface.Name + "." + iface_method.Name;
+
+                       proxy = container.TypeBuilder.DefineMethod (
+                               proxy_name,
+                               MethodAttributes.HideBySig |
+                               MethodAttributes.NewSlot |
+                               MethodAttributes.Virtual,
+                               CallingConventions.Standard | CallingConventions.HasThis,
+                               parent_method.ReturnType, args);
+
+                       ParameterData pd = Invocation.GetParameterData (iface_method);
+                       proxy.DefineParameter (0, ParameterAttributes.None, "");
+                       for (int i = 0; i < pd.Count; i++) {
+                               string name = pd.ParameterName (i);
+                               ParameterAttributes attr = Parameter.GetParameterAttributes (pd.ParameterModifier (i));
+                               ParameterBuilder pb = proxy.DefineParameter (i + 1, attr, name);
+                       }
+
+                       int top = args.Length;
+                       ILGenerator ig = proxy.GetILGenerator ();
+
+                       ig.Emit (OpCodes.Ldarg_0);
+                       for (int i = 0; i < top; i++){
+                               switch (i){
+                               case 0:
+                                       ig.Emit (OpCodes.Ldarg_1); break;
+                               case 1:
+                                       ig.Emit (OpCodes.Ldarg_2); break;
+                               case 2:
+                                       ig.Emit (OpCodes.Ldarg_3); break;
+                               default:
+                                       ig.Emit (OpCodes.Ldarg, i - 1); break;
+                               }
+                       }
+                       ig.Emit (OpCodes.Call, parent_method);
+                       ig.Emit (OpCodes.Ret);
+
+                       container.TypeBuilder.DefineMethodOverride (proxy, iface_method);
+               }
+               
+               /// <summary>
+               ///   This function tells whether one of our parent classes implements
+               ///   the given method (which turns out, it is valid to have an interface
+               ///   implementation in a parent
+               /// </summary>
+               bool ParentImplements (Type iface_type, MethodInfo mi)
+               {
+                       MethodSignature ms;
+                       
+                       Type [] args = TypeManager.GetArgumentTypes (mi);
+                       ms = new MethodSignature (mi.Name, mi.ReturnType, args);
+                       MemberList list = TypeContainer.FindMembers (
+                               container.TypeBuilder.BaseType, MemberTypes.Method | MemberTypes.Property,
+                               BindingFlags.Public | BindingFlags.Instance,
+                               MethodSignature.method_signature_filter, ms);
+
+                       if (list.Count == 0)
+                               return false;
+
+                       MethodInfo parent = (MethodInfo) list [0];
+                       if (!parent.IsAbstract)
+                               DefineProxy (iface_type, parent, mi, args);
+                       return true;
+               }
+
+               /// <summary>
+               ///   Verifies that any pending abstract methods or interface methods
+               ///   were implemented.
+               /// </summary>
+               public bool VerifyPendingMethods ()
+               {
+                       int top = pending_implementations.Length;
+                       bool errors = false;
+                       int i;
+                       
+                       for (i = 0; i < top; i++){
+                               Type type = pending_implementations [i].type;
+                               int j = 0;
+
+                               foreach (MethodInfo mi in pending_implementations [i].methods){
+                                       if (mi == null)
+                                               continue;
+
+                                       if (type.IsInterface){
+                                               MethodInfo need_proxy =
+                                                       pending_implementations [i].need_proxy [j];
+
+                                               if (need_proxy != null) {
+                                                       Type [] args = TypeManager.GetArgumentTypes (mi);
+                                                       DefineProxy (type, need_proxy, mi, args);
+                                                       continue;
+                                               }
+
+                                               if (ParentImplements (type, mi))
+                                                       continue;
+
+                                               if (pending_implementations [i].optional)
+                                                       continue;
+                                               
+                                               if (pending_implementations [i].found [j]) {
+                                                       string[] methodLabel = TypeManager.CSharpSignature (mi).Split ('.');
+                                                       Report.Error (536, container.Location,
+                                                                     "'{0}' does not implement interface member '{1}'. '{2}.{3}' " +
+                                                                     "is either static, not public, or has the wrong return type",
+                                                                     container.Name, TypeManager.CSharpSignature (mi),
+                                                                     container.Name, methodLabel[methodLabel.Length - 1]);
+                                               }
+                                               else { 
+                                                       Report.Error (535, container.Location, "'{0}' does not implement interface member '{1}'",
+                                                               container.Name, TypeManager.CSharpSignature (mi));
+                                               }
+                                       } else {
+                                               Report.Error (534, container.Location, "'{0}' does not implement inherited abstract member '{1}'",
+                                                       container.Name, TypeManager.CSharpSignature (mi));
+                                       }
+                                       errors = true;
+                                       j++;
+                               }
+                       }
+                       return errors;
+               }
+       } /* end of class */
+}
diff --git a/mcs/bmcs/report.cs b/mcs/bmcs/report.cs
new file mode 100644 (file)
index 0000000..d3a533c
--- /dev/null
@@ -0,0 +1,669 @@
+//
+// report.cs: report errors and warnings.
+//
+// Author: Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc. (http://www.ximian.com)
+//
+
+//
+// FIXME: currently our class library does not support custom number format strings
+//
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Diagnostics;
+using System.Reflection;
+
+namespace Mono.CSharp {
+
+       /// <summary>
+       ///   This class is used to report errors and warnings t te user.
+       /// </summary>
+       public class Report {
+               /// <summary>  
+               ///   Errors encountered so far
+               /// </summary>
+               static public int Errors;
+
+               /// <summary>  
+               ///   Warnings encountered so far
+               /// </summary>
+               static public int Warnings;
+
+               /// <summary>  
+               ///   Whether errors should be throw an exception
+               /// </summary>
+               static public bool Fatal;
+               
+               /// <summary>  
+               ///   Whether warnings should be considered errors
+               /// </summary>
+               static public bool WarningsAreErrors;
+
+               /// <summary>  
+               ///   Whether to dump a stack trace on errors. 
+               /// </summary>
+               static public bool Stacktrace;
+               
+               //
+               // If the 'expected' error code is reported then the
+                // compilation succeeds.
+               //
+               // Used for the test suite to excercise the error codes
+               //
+               static int expected_error = 0;
+
+               //
+               // Keeps track of the warnings that we are ignoring
+               //
+               static Hashtable warning_ignore_table;
+
+               static Hashtable warning_regions_table;
+
+               /// <summary>
+               /// List of symbols related to reported error/warning. You have to fill it before error/warning is reported.
+               /// </summary>
+               static StringCollection extra_information = new StringCollection ();
+
+               abstract class AbstractMessage {
+
+                       static void Check (int code)
+                       {
+                               if (code == expected_error) {
+                                       Environment.Exit (0);
+                               }
+                       }
+
+                       public abstract bool IsWarning { get; }
+
+                       public abstract string MessageType { get; }
+
+                       public virtual void Print (int code, string location, string text)
+                       {
+                               if (code < 0)
+                                       code = 8000-code;
+
+                               StringBuilder msg = new StringBuilder ();
+                               if (location.Length != 0) {
+                                       msg.Append (location);
+                                       msg.Append (' ');
+                               }
+                               msg.AppendFormat ("{0} CS{1:0000}: {2}", MessageType, code, text);
+                               Console.Error.WriteLine (msg.ToString ());
+
+                               foreach (string s in extra_information) 
+                                       Console.Error.WriteLine (s + MessageType);
+
+                               extra_information.Clear ();
+
+                               if (Stacktrace)
+                                       Console.WriteLine (FriendlyStackTrace (new StackTrace (true)));
+
+                               if (Fatal) {
+                                       if (!IsWarning || WarningsAreErrors)
+                                               throw new Exception (text);
+                               }
+
+                               Check (code);
+                       }
+
+                       public virtual void Print (int code, Location location, string text)
+                       {
+                               if (location.Equals (Location.Null)) {
+                                       Print (code, "", text);
+                                       return;
+                               }
+                               Print (code, String.Format ("{0}({1})", location.Name, location.Row), text);
+                       }
+               }
+
+               sealed class WarningMessage: AbstractMessage {
+                       Location loc = Location.Null;
+                       readonly int Level;
+
+                       public WarningMessage ():
+                               this (-1) {}
+
+                       public WarningMessage (int level)
+                       {
+                               Level = level;
+                       }
+
+                       public override bool IsWarning {
+                               get { return true; }
+                       }
+
+                       bool IsEnabled (int code)
+                       {
+                               if (RootContext.WarningLevel < Level)
+                                       return false;
+
+                               if (warning_ignore_table != null) {
+                                       if (warning_ignore_table.Contains (code)) {
+                                               return false;
+                                       }
+                               }
+
+                               if (warning_regions_table == null || loc.Equals (Location.Null))
+                                       return true;
+
+                               WarningRegions regions = (WarningRegions)warning_regions_table [loc.Name];
+                               return regions.IsWarningEnabled (code, loc.Row);
+                       }
+
+                       public override void Print(int code, string location, string text)
+                       {
+                               if (!IsEnabled (code)) {
+                                       extra_information.Clear ();
+                                       return;
+                               }
+
+                               if (WarningsAreErrors) {
+                                       new ErrorMessage ().Print (code, location, text);
+                                       return;
+                               }
+
+                               Warnings++;
+                               base.Print (code, location, text);
+                       }
+
+                       public override void Print(int code, Location location, string text)
+                       {
+                               loc = location;
+                               base.Print (code, location, text);
+                       }
+
+                       public override string MessageType {
+                               get {
+                                       return "warning";
+                               }
+                       }
+               }
+
+               sealed class ErrorMessage: AbstractMessage {
+
+                       public override void Print(int code, string location, string text)
+                       {
+                               Errors++;
+                               base.Print (code, location, text);
+                       }
+
+                       public override bool IsWarning {
+                               get { return false; }
+                       }
+
+                       public override string MessageType {
+                               get {
+                                       return "error";
+                               }
+                       }
+
+               }
+
+               public static void FeatureIsNotStandardized (Location loc, string feature)
+               {
+                       Report.Error (1644, loc, "Feature '{0}' cannot be used because it is not part of the standardized ISO C# language specification", feature);
+               }
+               
+               public static string FriendlyStackTrace (Exception e)
+               {
+                       return FriendlyStackTrace (new StackTrace (e, true));
+               }
+               
+               static string FriendlyStackTrace (StackTrace t)
+               {               
+                       StringBuilder sb = new StringBuilder ();
+                       
+                       bool foundUserCode = false;
+                       
+                       for (int i = 0; i < t.FrameCount; i++) {
+                               StackFrame f = t.GetFrame (i);
+                               MethodBase mb = f.GetMethod ();
+                               
+                               if (!foundUserCode && mb.ReflectedType == typeof (Report))
+                                       continue;
+                               
+                               foundUserCode = true;
+                               
+                               sb.Append ("\tin ");
+                               
+                               if (f.GetFileLineNumber () > 0)
+                                       sb.AppendFormat ("(at {0}:{1}) ", f.GetFileName (), f.GetFileLineNumber ());
+                               
+                               sb.AppendFormat ("{0}.{1} (", mb.ReflectedType.Name, mb.Name);
+                               
+                               bool first = true;
+                               foreach (ParameterInfo pi in mb.GetParameters ()) {
+                                       if (!first)
+                                               sb.Append (", ");
+                                       first = false;
+                                       
+                                       sb.Append (TypeManager.CSharpName (pi.ParameterType));
+                               }
+                               sb.Append (")\n");
+                       }
+       
+                       return sb.ToString ();
+               }
+
+               // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+               // IF YOU ADD A NEW WARNING YOU HAVE TO DUPLICATE ITS ID HERE
+               //
+               public static bool IsValidWarning (int code)
+               {
+                       int[] all_warnings = new int[] {
+                               28, 67, 78, 105, 108, 109, 114, 192, 168, 169, 183, 184, 219, 251, 612, 618, 626, 628, 642, 649,
+                               659, 660, 661, 672, 1030, 1522, 1616, 1691, 1692, 1901, 2002, 2023, 3012, 3019, 8024, 8028
+                       };
+                       
+                       foreach (int i in all_warnings) {
+                               if (i == code)
+                                       return true;
+                       }
+                       return false;
+               }
+               
+               static public void LocationOfPreviousError (Location loc)
+               {
+                       Console.Error.WriteLine (String.Format ("{0}({1}) (Location of symbol related to previous error)", loc.Name, loc.Row));
+               }    
+        
+               static public void RuntimeMissingSupport (Location loc, string feature) 
+               {
+                       Report.Error (-88, loc, "Your .NET Runtime does not support '{0}'. Please use the latest Mono runtime instead.", feature);
+               }
+
+               /// <summary>
+               /// In most error cases is very useful to have information about symbol that caused the error.
+               /// Call this method before you call Report.Error when it makes sense.
+               /// </summary>
+               static public void SymbolRelatedToPreviousError (Location loc, string symbol)
+               {
+                       SymbolRelatedToPreviousError (String.Format ("{0}({1})", loc.Name, loc.Row), symbol);
+               }
+
+               static public void SymbolRelatedToPreviousError (MemberInfo mi)
+               {
+                       TypeContainer temp_ds = TypeManager.LookupGenericTypeContainer (mi.DeclaringType);
+                       if (temp_ds == null) {
+                               SymbolRelatedToPreviousError (mi.DeclaringType.Assembly.Location, TypeManager.GetFullNameSignature (mi));
+                       } else {
+                               MethodBase mb = mi as MethodBase;
+                               if (mb != null) {
+                                       while (mb.Mono_IsInflatedMethod)
+                                               mb = mb.GetGenericMethodDefinition ();
+                                       IMethodData md = TypeManager.GetMethod (mb);
+                                       SymbolRelatedToPreviousError (md.Location, md.GetSignatureForError (temp_ds));
+                                       return;
+                               }
+
+                               string name = String.Concat (temp_ds.Name, ".", mi.Name);
+                               MemberCore mc = temp_ds.GetDefinition (name);
+                               SymbolRelatedToPreviousError (mc);
+                       }
+               }
+
+               static public void SymbolRelatedToPreviousError (MemberCore mc)
+               {
+                       SymbolRelatedToPreviousError (mc.Location, mc.GetSignatureForError ());
+               }
+
+               static public void SymbolRelatedToPreviousError (Type type)
+               {
+                       DeclSpace temp_ds = TypeManager.LookupDeclSpace (type);
+                       if (temp_ds == null)
+                               SymbolRelatedToPreviousError (type.Assembly.Location, TypeManager.CSharpName (type));
+                       else 
+                               SymbolRelatedToPreviousError (temp_ds.Location, TypeManager.CSharpName (type));
+               }
+
+               static void SymbolRelatedToPreviousError (string loc, string symbol)
+               {
+                       extra_information.Add (String.Format ("{0}: '{1}' (name of symbol related to previous ", loc, symbol));
+               }
+
+               public static void ExtraInformation (Location loc, string msg)
+               {
+                       extra_information.Add (String.Format ("{0}({1}) {2}", loc.Name, loc.Row, msg));
+               }
+
+               public static WarningRegions RegisterWarningRegion (Location location)
+               {
+                       if (warning_regions_table == null)
+                               warning_regions_table = new Hashtable ();
+
+                       WarningRegions regions = (WarningRegions)warning_regions_table [location.Name];
+                       if (regions == null) {
+                               regions = new WarningRegions ();
+                               warning_regions_table.Add (location.Name, regions);
+                       }
+                       return regions;
+               }
+
+               static public void Warning (int code, int level, Location loc, string format, params object[] args)
+               {
+                       WarningMessage w = new WarningMessage (level);
+                       w.Print (code, loc, String.Format (format, args));
+               }
+
+               static public void Warning (int code, Location loc, string format, params object[] args)
+               {
+                       WarningMessage w = new WarningMessage ();
+                       w.Print (code, loc, String.Format (format, args));
+               }
+
+               static public void Warning (int code, string format, params object[] args)
+               {
+                       Warning (code, Location.Null, String.Format (format, args));
+               }
+
+               /// <summary>
+               /// Did you test your WarningLevel, that you use this method
+               /// </summary>
+               static public void Warning (int code, string text)
+               {
+                       Warning (code, Location.Null, text);
+               }
+
+               static public void Error (int code, string format, params object[] args)
+               {
+                       Error (code, Location.Null, String.Format (format, args));
+               }
+
+               static public void Error (int code, Location loc, string format, params object[] args)
+               {
+                       ErrorMessage e = new ErrorMessage ();
+                       e.Print (code, loc, String.Format (format, args));
+               }
+
+               static public void SetIgnoreWarning (int code)
+               {
+                       if (warning_ignore_table == null)
+                               warning_ignore_table = new Hashtable ();
+
+                       warning_ignore_table [code] = true;
+               }
+               
+               static public int ExpectedError {
+                       set {
+                               expected_error = value;
+                       }
+                       get {
+                               return expected_error;
+                       }
+               }
+
+               public static int DebugFlags = 0;
+
+               [Conditional ("MCS_DEBUG")]
+               static public void Debug (string message, params object[] args)
+               {
+                       Debug (4, message, args);
+               }
+                       
+               [Conditional ("MCS_DEBUG")]
+               static public void Debug (int category, string message, params object[] args)
+               {
+                       if ((category & DebugFlags) == 0)
+                               return;
+
+                       StringBuilder sb = new StringBuilder (message);
+
+                       if ((args != null) && (args.Length > 0)) {
+                               sb.Append (": ");
+
+                               bool first = true;
+                               foreach (object arg in args) {
+                                       if (first)
+                                               first = false;
+                                       else
+                                               sb.Append (", ");
+                                       if (arg == null)
+                                               sb.Append ("null");
+                                       else if (arg is ICollection)
+                                               sb.Append (PrintCollection ((ICollection) arg));
+                                       else
+                                               sb.Append (arg);
+                               }
+                       }
+
+                       Console.WriteLine (sb.ToString ());
+               }
+
+               static public string PrintCollection (ICollection collection)
+               {
+                       StringBuilder sb = new StringBuilder ();
+
+                       sb.Append (collection.GetType ());
+                       sb.Append ("(");
+
+                       bool first = true;
+                       foreach (object o in collection) {
+                               if (first)
+                                       first = false;
+                               else
+                                       sb.Append (", ");
+                               sb.Append (o);
+                       }
+
+                       sb.Append (")");
+                       return sb.ToString ();
+               }
+       }
+
+       public enum TimerType {
+               FindMembers     = 0,
+               TcFindMembers   = 1,
+               MemberLookup    = 2,
+               CachedLookup    = 3,
+               CacheInit       = 4,
+               MiscTimer       = 5,
+               CountTimers     = 6
+       }
+
+       public enum CounterType {
+               FindMembers     = 0,
+               MemberCache     = 1,
+               MiscCounter     = 2,
+               CountCounters   = 3
+       }
+
+       public class Timer
+       {
+               static DateTime[] timer_start;
+               static TimeSpan[] timers;
+               static long[] timer_counters;
+               static long[] counters;
+
+               static Timer ()
+               {
+                       timer_start = new DateTime [(int) TimerType.CountTimers];
+                       timers = new TimeSpan [(int) TimerType.CountTimers];
+                       timer_counters = new long [(int) TimerType.CountTimers];
+                       counters = new long [(int) CounterType.CountCounters];
+
+                       for (int i = 0; i < (int) TimerType.CountTimers; i++) {
+                               timer_start [i] = DateTime.Now;
+                               timers [i] = TimeSpan.Zero;
+                       }
+               }
+
+               [Conditional("TIMER")]
+               static public void IncrementCounter (CounterType which)
+               {
+                       ++counters [(int) which];
+               }
+
+               [Conditional("TIMER")]
+               static public void StartTimer (TimerType which)
+               {
+                       timer_start [(int) which] = DateTime.Now;
+               }
+
+               [Conditional("TIMER")]
+               static public void StopTimer (TimerType which)
+               {
+                       timers [(int) which] += DateTime.Now - timer_start [(int) which];
+                       ++timer_counters [(int) which];
+               }
+
+               [Conditional("TIMER")]
+               static public void ShowTimers ()
+               {
+                       ShowTimer (TimerType.FindMembers, "- FindMembers timer");
+                       ShowTimer (TimerType.TcFindMembers, "- TypeContainer.FindMembers timer");
+                       ShowTimer (TimerType.MemberLookup, "- MemberLookup timer");
+                       ShowTimer (TimerType.CachedLookup, "- CachedLookup timer");
+                       ShowTimer (TimerType.CacheInit, "- Cache init");
+                       ShowTimer (TimerType.MiscTimer, "- Misc timer");
+
+                       ShowCounter (CounterType.FindMembers, "- Find members");
+                       ShowCounter (CounterType.MemberCache, "- Member cache");
+                       ShowCounter (CounterType.MiscCounter, "- Misc counter");
+               }
+
+               static public void ShowCounter (CounterType which, string msg)
+               {
+                       Console.WriteLine ("{0} {1}", counters [(int) which], msg);
+               }
+
+               static public void ShowTimer (TimerType which, string msg)
+               {
+                       Console.WriteLine (
+                               "[{0:00}:{1:000}] {2} (used {3} times)",
+                               (int) timers [(int) which].TotalSeconds,
+                               timers [(int) which].Milliseconds, msg,
+                               timer_counters [(int) which]);
+               }
+       }
+
+       public class InternalErrorException : Exception {
+               public InternalErrorException ()
+                       : base ("Internal error")
+               {
+               }
+
+               public InternalErrorException (string message)
+                       : base (message)
+               {
+               }
+       }
+
+       /// <summary>
+       /// Handles #pragma warning
+       /// </summary>
+       public class WarningRegions {
+
+               abstract class PragmaCmd
+               {
+                       public int Line;
+
+                       protected PragmaCmd (int line)
+                       {
+                               Line = line;
+                       }
+
+                       public abstract bool IsEnabled (int code, bool previous);
+               }
+               
+               class Disable: PragmaCmd
+               {
+                       int code;
+                       public Disable (int line, int code)
+                               : base (line)
+                       {
+                               this.code = code;
+                       }
+
+                       public override bool IsEnabled (int code, bool previous)
+                       {
+                               return this.code == code ? false : previous;
+                       }
+               }
+
+               class DisableAll: PragmaCmd
+               {
+                       public DisableAll (int line)
+                               : base (line) {}
+
+                       public override bool IsEnabled(int code, bool previous)
+                       {
+                               return false;
+                       }
+               }
+
+               class Enable: PragmaCmd
+               {
+                       int code;
+                       public Enable (int line, int code)
+                               : base (line)
+                       {
+                               this.code = code;
+                       }
+
+                       public override bool IsEnabled(int code, bool previous)
+                       {
+                               return this.code == code ? true : previous;
+                       }
+               }
+
+               class EnableAll: PragmaCmd
+               {
+                       public EnableAll (int line)
+                               : base (line) {}
+
+                       public override bool IsEnabled(int code, bool previous)
+                       {
+                               return true;
+                       }
+               }
+
+
+               ArrayList regions = new ArrayList ();
+
+               public void WarningDisable (int line)
+               {
+                       regions.Add (new DisableAll (line));
+               }
+
+               public void WarningDisable (Location location, int code)
+               {
+                       if (CheckWarningCode (code, location))
+                               regions.Add (new Disable (location.Row, code));
+               }
+
+               public void WarningEnable (int line)
+               {
+                       regions.Add (new EnableAll (line));
+               }
+
+               public void WarningEnable (Location location, int code)
+               {
+                       if (CheckWarningCode (code, location))
+                               regions.Add (new Enable (location.Row, code));
+               }
+
+               public bool IsWarningEnabled (int code, int src_line)
+               {
+                       bool result = true;
+                       foreach (PragmaCmd pragma in regions) {
+                               if (src_line < pragma.Line)
+                                       break;
+
+                               result = pragma.IsEnabled (code, result);
+                       }
+                       return result;
+               }
+
+               bool CheckWarningCode (int code, Location loc)
+               {
+                       if (Report.IsValidWarning (code))
+                               return true;
+
+                       Report.Warning (1691, 1, loc, "'{0}' is not a valid warning number", code);
+                       return false;
+               }
+       }
+}
diff --git a/mcs/bmcs/rootcontext.cs b/mcs/bmcs/rootcontext.cs
new file mode 100644 (file)
index 0000000..3fd268b
--- /dev/null
@@ -0,0 +1,803 @@
+//
+// rootcontext.cs: keeps track of our tree representation, and assemblies loaded.
+//
+// Author: Miguel de Icaza (miguel@ximian.com)
+//         Ravi Pratap     (ravi@ximian.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+// (C) 2004 Novell, Inc
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Diagnostics;
+using System.Xml;
+
+namespace Mono.CSharp {
+
+       public enum LanguageVersion
+       {
+               Default = 0,
+               ISO_1   = 1
+       }
+
+       public class RootContext {
+
+               //
+               // Contains the parsed tree
+               //
+               static Tree tree;
+
+               //
+               // This hashtable contains all of the #definitions across the source code
+               // it is used by the ConditionalAttribute handler.
+               //
+               public static Hashtable AllDefines = new Hashtable ();
+               
+               //
+               // Whether we are being linked against the standard libraries.
+               // This is only used to tell whether `System.Object' should
+               // have a parent or not.
+               //
+               public static bool StdLib = true;
+
+               //
+               // This keeps track of the order in which classes were defined
+               // so that we can poulate them in that order.
+               //
+               // Order is important, because we need to be able to tell by
+               // examining the parent's list of methods which ones are virtual
+               // or abstract as well as the parent names (to implement new, 
+               // override).
+               //
+               static ArrayList type_container_resolve_order;
+               static ArrayList attribute_types;
+
+               //
+               // Holds a reference to the Private Implementation Details
+               // class.
+               //
+               static ArrayList helper_classes;
+               
+               static TypeBuilder impl_details_class;
+
+               public static int WarningLevel = 2;
+
+               public static Target Target = Target.Exe;
+               public static string TargetExt = ".exe";
+
+               public static bool VerifyClsCompliance = true;
+
+               public static LanguageVersion Version = LanguageVersion.Default;
+
+               //
+               // We keep strongname related info here because
+               // it's also used as complier options from CSC 8.x
+               //
+               public static string StrongNameKeyFile;
+               public static string StrongNameKeyContainer;
+               public static bool StrongNameDelaySign = false;
+
+               //
+               // If set, enable XML documentation generation
+               //
+               public static Documentation Documentation;
+
+               //
+               // Constructor
+               //
+               static RootContext ()
+               {
+                       tree = new Tree ();
+                       type_container_resolve_order = new ArrayList ();
+               }
+
+               public static bool NeedsEntryPoint {
+                       get {
+                               return RootContext.Target == Target.Exe || RootContext.Target == Target.WinExe;
+                       }
+               }
+
+               static public Tree Tree {
+                       get {
+                               return tree;
+                       }
+               }
+
+               static public string MainClass;
+               
+               public static void RegisterOrder (TypeContainer tc)
+               {
+                       type_container_resolve_order.Add (tc);
+               }
+
+               public static void RegisterAttribute (TypeContainer tc)
+               {
+                       if (attribute_types == null)
+                               attribute_types = new ArrayList ();
+                       
+                       attribute_types.Add (tc);
+               }
+               
+               // 
+               // The default compiler checked state
+               //
+               static public bool Checked = false;
+
+               //
+               // Whether to allow Unsafe code
+               //
+               static public bool Unsafe = false;
+               
+               static string MakeFQN (string nsn, string name)
+               {
+                       if (nsn == "")
+                               return name;
+                       return String.Concat (nsn, ".", name);
+               }
+
+               // <remarks>
+               //   This function is used to resolve the hierarchy tree.
+               //   It processes interfaces, structs and classes in that order.
+               //
+               //   It creates the TypeBuilder's as it processes the user defined
+               //   types.  
+               // </remarks>
+               static public void ResolveTree ()
+               {
+                       //
+                       // Process the attribute types separately and before anything else
+                       //
+                       if (attribute_types != null)
+                               foreach (TypeContainer tc in attribute_types)
+                                       tc.DefineType ();
+                       
+                       //
+                       // Interfaces are processed next, as classes and
+                       // structs might inherit from an object or implement
+                       // a set of interfaces, we need to be able to tell
+                       // them appart by just using the TypeManager.
+                       //
+                       TypeContainer root = Tree.Types;
+
+                       ArrayList ifaces = root.Interfaces;
+                       if (ifaces != null){
+                               foreach (Interface i in ifaces) 
+                                       i.DefineType ();
+                       }
+
+                       foreach (TypeContainer tc in root.Types)
+                               tc.DefineType ();
+
+                       if (root.Delegates != null)
+                               foreach (Delegate d in root.Delegates) 
+                                       d.DefineType ();
+
+                       if (root.Enums != null)
+                               foreach (Enum e in root.Enums)
+                                       e.DefineType ();
+               }
+
+               static void Error_TypeConflict (string name, Location loc)
+               {
+                       Report.Error (
+                               520, loc, "`" + name + "' conflicts with a predefined type");
+               }
+
+               static void Error_TypeConflict (string name)
+               {
+                       Report.Error (
+                               520, "`" + name + "' conflicts with a predefined type");
+               }
+
+               //
+               // Resolves a single class during the corlib bootstrap process
+               //
+               static TypeBuilder BootstrapCorlib_ResolveClass (TypeContainer root, string name)
+               {
+                       object o = root.GetDefinition (name);
+                       if (o == null){
+                               Report.Error (518, "The predefined type `" + name + "' is not defined");
+                               return null;
+                       }
+
+                       if (!(o is Class)){
+                               if (o is DeclSpace){
+                                       DeclSpace d = (DeclSpace) o;
+
+                                       Error_TypeConflict (name, d.Location);
+                               } else
+                                       Error_TypeConflict (name);
+
+                               return null;
+                       }
+
+                       return ((DeclSpace) o).DefineType ();
+               }
+
+               //
+               // Resolves a struct during the corlib bootstrap process
+               //
+               static void BootstrapCorlib_ResolveStruct (TypeContainer root, string name)
+               {
+                       object o = root.GetDefinition (name);
+                       if (o == null){
+                               Report.Error (518, "The predefined type `" + name + "' is not defined");
+                               return;
+                       }
+
+                       if (!(o is Struct)){
+                               if (o is DeclSpace){
+                                       DeclSpace d = (DeclSpace) o;
+
+                                       Error_TypeConflict (name, d.Location);
+                               } else
+                                       Error_TypeConflict (name);
+
+                               return;
+                       }
+
+                       ((DeclSpace) o).DefineType ();
+               }
+
+               //
+               // Resolves a struct during the corlib bootstrap process
+               //
+               static void BootstrapCorlib_ResolveInterface (TypeContainer root, string name)
+               {
+                       object o = root.GetDefinition (name);
+                       if (o == null){
+                               Report.Error (518, "The predefined type `" + name + "' is not defined");
+                               return;
+                       }
+
+                       if (!(o is Interface)){
+                               if (o is DeclSpace){
+                                       DeclSpace d = (DeclSpace) o;
+
+                                       Error_TypeConflict (name, d.Location);
+                               } else
+                                       Error_TypeConflict (name);
+
+                               return;
+                       }
+
+                       ((DeclSpace) o).DefineType ();
+               }
+
+               //
+               // Resolves a delegate during the corlib bootstrap process
+               //
+               static void BootstrapCorlib_ResolveDelegate (TypeContainer root, string name)
+               {
+                       object o = root.GetDefinition (name);
+                       if (o == null){
+                               Report.Error (518, "The predefined type `" + name + "' is not defined");
+                               Environment.Exit (1);
+                       }
+
+                       if (!(o is Delegate)){
+                               Error_TypeConflict (name);
+                               return;
+                       }
+
+                       ((DeclSpace) o).DefineType ();
+               }
+               
+
+               /// <summary>
+               ///    Resolves the core types in the compiler when compiling with --nostdlib
+               /// </summary>
+               static public void ResolveCore ()
+               {
+                       TypeContainer root = Tree.Types;
+
+                       TypeManager.object_type = BootstrapCorlib_ResolveClass (root, "System.Object");
+                       TypeManager.value_type = BootstrapCorlib_ResolveClass (root, "System.ValueType");
+                       TypeManager.attribute_type = BootstrapCorlib_ResolveClass (root, "System.Attribute");
+                       
+                       string [] interfaces_first_stage = {
+                               "System.IComparable", "System.ICloneable",
+                               "System.IConvertible",
+                               
+                               "System.Collections.IEnumerable",
+                               "System.Collections.ICollection",
+                               "System.Collections.IEnumerator",
+                               "System.Collections.IList", 
+                               "System.IAsyncResult",
+                               "System.IDisposable",
+                               
+                               "System.Runtime.Serialization.ISerializable",
+                               "System.Runtime.InteropServices._Exception",
+
+                               "System.Reflection.IReflect",
+                               "System.Reflection.ICustomAttributeProvider",
+
+                               //
+                               // Generic types
+                               //
+                               "System.Collections.Generic.IEnumerator`1",
+                               "System.Collections.Generic.IEnumerable`1"
+                       };
+
+                       foreach (string iname in interfaces_first_stage)
+                               BootstrapCorlib_ResolveInterface (root, iname);
+
+                       //
+                       // These are the base value types
+                       //
+                       string [] structs_first_stage = {
+                               "System.Byte",    "System.SByte",
+                               "System.Int16",   "System.UInt16",
+                               "System.Int32",   "System.UInt32",
+                               "System.Int64",   "System.UInt64",
+                       };
+
+                       foreach (string cname in structs_first_stage)
+                               BootstrapCorlib_ResolveStruct (root, cname);
+
+                       //
+                       // Now, we can load the enumerations, after this point,
+                       // we can use enums.
+                       //
+                       TypeManager.InitEnumUnderlyingTypes ();
+
+                       string [] structs_second_stage = {
+                               "System.Single",  "System.Double",
+                               "System.Char",    "System.Boolean",
+                               "System.Decimal", "System.Void",
+                               "System.RuntimeFieldHandle",
+                               "System.RuntimeArgumentHandle",
+                               "System.RuntimeTypeHandle",
+                               "System.IntPtr",
+                               "System.TypedReference",
+                               "System.ArgIterator"
+                       };
+                       
+                       foreach (string cname in structs_second_stage)
+                               BootstrapCorlib_ResolveStruct (root, cname);
+                       
+                       //
+                       // These are classes that depends on the core interfaces
+                       //
+                       string [] classes_second_stage = {
+                               "System.Reflection.MemberInfo",
+                               "System.Type",
+                               "System.Exception",
+                               "System.Activator",
+
+                               //
+                               // These are not really important in the order, but they
+                               // are used by the compiler later on (typemanager/CoreLookupType-d)
+                               //
+                               "System.Runtime.CompilerServices.RuntimeHelpers",
+                               "System.Reflection.DefaultMemberAttribute",
+                               "System.Threading.Monitor",
+                               
+                               "System.AttributeUsageAttribute",
+                               "System.Runtime.InteropServices.DllImportAttribute",
+                               "System.Runtime.CompilerServices.MethodImplAttribute",
+                               "System.Runtime.InteropServices.MarshalAsAttribute",
+                               "System.Runtime.CompilerServices.NewConstraintAttribute",
+                               "System.Diagnostics.ConditionalAttribute",
+                               "System.ObsoleteAttribute",
+                               "System.ParamArrayAttribute",
+                               "System.CLSCompliantAttribute",
+                               "System.Security.UnverifiableCodeAttribute",
+                               "System.Security.Permissions.SecurityAttribute",
+                               "System.Runtime.CompilerServices.IndexerNameAttribute",
+                               "System.Runtime.CompilerServices.DecimalConstantAttribute",
+                               "System.Runtime.InteropServices.InAttribute",
+                               "System.Runtime.InteropServices.StructLayoutAttribute",
+                               "System.Runtime.InteropServices.FieldOffsetAttribute",
+                               "System.InvalidOperationException",
+                               "System.NotSupportedException",
+                               "System.MarshalByRefObject",
+                               "System.Security.CodeAccessPermission"
+                       };
+
+                       // We must store them here before calling BootstrapCorlib_ResolveDelegate.
+                       TypeManager.string_type = BootstrapCorlib_ResolveClass (root, "System.String");
+                       TypeManager.enum_type = BootstrapCorlib_ResolveClass (root, "System.Enum");
+                       TypeManager.array_type = BootstrapCorlib_ResolveClass (root, "System.Array");
+                       TypeManager.multicast_delegate_type = BootstrapCorlib_ResolveClass (root, "System.MulticastDelegate");
+                       TypeManager.delegate_type = BootstrapCorlib_ResolveClass (root, "System.Delegate");
+                       
+                       foreach (string cname in classes_second_stage)
+                               BootstrapCorlib_ResolveClass (root, cname);
+
+                       BootstrapCorlib_ResolveDelegate (root, "System.AsyncCallback");
+               }
+                       
+               // <summary>
+               //   Closes all open types
+               // </summary>
+               //
+               // <remarks>
+               //   We usually use TypeBuilder types.  When we are done
+               //   creating the type (which will happen after we have added
+               //   methods, fields, etc) we need to "Define" them before we
+               //   can save the Assembly
+               // </remarks>
+               static public void CloseTypes ()
+               {
+                       TypeContainer root = Tree.Types;
+                       
+                       if (root.Enums != null)
+                               foreach (Enum en in root.Enums)
+                                       en.CloseType ();
+
+                       if (attribute_types != null)
+                               foreach (TypeContainer tc in attribute_types)
+                                       tc.CloseType ();
+                       
+                       //
+                       // We do this in two passes, first we close the structs,
+                       // then the classes, because it seems the code needs it this
+                       // way.  If this is really what is going on, we should probably
+                       // make sure that we define the structs in order as well.
+                       //
+                       foreach (TypeContainer tc in type_container_resolve_order){
+                               if (tc.Kind == Kind.Struct && tc.Parent == tree.Types){
+                                       tc.CloseType ();
+                               }
+                       }
+
+                       foreach (TypeContainer tc in type_container_resolve_order){
+                               if (!(tc.Kind == Kind.Struct && tc.Parent == tree.Types))
+                                       tc.CloseType ();                                        
+                       }
+                       
+                       if (root.Delegates != null)
+                               foreach (Delegate d in root.Delegates)
+                                       d.CloseType ();
+
+
+                       //
+                       // If we have a <PrivateImplementationDetails> class, close it
+                       //
+                       if (helper_classes != null){
+                               foreach (TypeBuilder type_builder in helper_classes)
+                                       type_builder.CreateType ();
+                       }
+                       
+                       attribute_types = null;
+                       type_container_resolve_order = null;
+                       helper_classes = null;
+                       //tree = null;
+                       TypeManager.CleanUp ();
+               }
+
+               /// <summary>
+               ///   Used to register classes that need to be closed after all the
+               ///   user defined classes
+               /// </summary>
+               public static void RegisterHelperClass (TypeBuilder helper_class)
+               {
+                       if (helper_classes == null)
+                               helper_classes = new ArrayList ();
+                       helper_classes.Add (helper_class);
+               }
+               
+               //
+               // This idea is from Felix Arrese-Igor
+               //
+               // Returns : the implicit parent of a composite namespace string
+               //   eg. Implicit parent of A.B is A
+               //
+               static public string ImplicitParent (string ns)
+               {
+                       int i = ns.LastIndexOf ('.');
+                       if (i < 0)
+                               return null;
+                       
+                       return ns.Substring (0, i);
+               }
+
+               static Type NamespaceLookup (DeclSpace ds, string name, int num_type_args, Location loc)
+               {
+                       IAlias result = ds.NamespaceEntry.LookupNamespaceOrType (ds, name, loc);
+                       if (result == null)
+                               return null;
+
+                       if (!result.IsType)
+                               return null;
+
+                       TypeExpr texpr = result.ResolveAsType (ds.EmitContext);
+                       if (texpr == null)
+                               return null;
+
+                       return texpr.Type;
+               }
+               
+               static public Type LookupType (DeclSpace ds, string name, bool silent, Location loc)
+               {
+                       return LookupType (ds, name, silent, 0, loc);
+               }
+
+               //
+               // Public function used to locate types, this can only
+               // be used after the ResolveTree function has been invoked.
+               //
+               // Returns: Type or null if they type can not be found.
+               //
+               // Come to think of it, this should be a DeclSpace
+               //
+               static public Type LookupType (DeclSpace ds, string name, bool silent,
+                                              int num_type_params, Location loc)
+               {
+                       Type t;
+
+                       if (ds.Cache.Contains (name)){
+                               t = (Type) ds.Cache [name];
+                               if (t != null)
+                                       return t;
+                       } else {
+                               //
+                               // For the case the type we are looking for is nested within this one
+                               // or is in any base class
+                               //
+                               DeclSpace containing_ds = ds;
+                               while (containing_ds != null){
+                                       Type current_type = containing_ds.TypeBuilder;
+                                       
+                                       while (current_type != null) {
+                                               //
+                                               // nested class
+                                               //
+                                               Type type = TypeManager.LookupType (current_type.FullName + "." + name);
+                                               if (type != null){
+                                                       t = ds.ResolveNestedType (type, loc);
+                                                       ds.Cache [name] = t;
+                                                       return t;
+                                               }
+                                               
+                                               current_type = current_type.BaseType;
+                                       }
+                                       
+                                       containing_ds = containing_ds.Parent;
+                               }
+                               
+                               t = NamespaceLookup (ds, name, num_type_params, loc);
+                               if (!silent || t != null){
+                                       ds.Cache [name] = t;
+                                       return t;
+                               }
+                       }
+
+                       if (!silent)
+                               Report.Error (246, loc, "Cannot find type `"+name+"'");
+                       
+                       return null;
+               }
+
+               // <summary>
+               //   This is the silent version of LookupType, you can use this
+               //   to `probe' for a type
+               // </summary>
+               static public Type LookupType (TypeContainer tc, string name, Location loc)
+               {
+                       return LookupType (tc, name, true, loc);
+               }
+
+               static void Report1530 (Location loc)
+               {
+                       Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
+               }
+               
+               static public void PopulateCoreType (TypeContainer root, string name)
+               {
+                       DeclSpace ds = (DeclSpace) root.GetDefinition (name);
+
+                       ds.DefineMembers (root);
+                       ds.Define ();
+               }
+               
+               static public void BootCorlib_PopulateCoreTypes ()
+               {
+                       TypeContainer root = tree.Types;
+
+                       PopulateCoreType (root, "System.Object");
+                       PopulateCoreType (root, "System.ValueType");
+                       PopulateCoreType (root, "System.Attribute");
+               }
+               
+               // <summary>
+               //   Populates the structs and classes with fields and methods
+               // </summary>
+               //
+               // This is invoked after all interfaces, structs and classes
+               // have been defined through `ResolveTree' 
+               static public void PopulateTypes ()
+               {
+                       TypeContainer root = Tree.Types;
+
+                       if (attribute_types != null)
+                               foreach (TypeContainer tc in attribute_types)
+                                       tc.DefineMembers (root);
+
+                       if (type_container_resolve_order != null){
+                               if (RootContext.StdLib){
+                                       foreach (TypeContainer tc in type_container_resolve_order)
+                                               tc.DefineMembers (root);
+                               } else {
+                                       foreach (TypeContainer tc in type_container_resolve_order) {
+                                               // When compiling corlib, these types have already been
+                                               // populated from BootCorlib_PopulateCoreTypes ().
+                                               if (((tc.Name == "System.Object") ||
+                                                    (tc.Name == "System.Attribute") ||
+                                                    (tc.Name == "System.ValueType")))
+                                               continue;
+
+                                               tc.DefineMembers (root);
+                                       }
+                               } 
+                       }
+
+                       ArrayList delegates = root.Delegates;
+                       if (delegates != null){
+                               foreach (Delegate d in delegates)
+                                       if ((d.ModFlags & Modifiers.NEW) == 0)
+                                               d.DefineMembers (root);
+                                       else
+                                               Report1530 (d.Location);
+                       }
+
+                       ArrayList enums = root.Enums;
+                       if (enums != null){
+                               foreach (Enum en in enums)
+                                       if ((en.ModFlags & Modifiers.NEW) == 0)
+                                               en.DefineMembers (root);
+                                       else
+                                               Report1530 (en.Location);
+                       }
+
+                       //
+                       // Check for cycles in the struct layout
+                       //
+                       if (type_container_resolve_order != null){
+                               Hashtable seen = new Hashtable ();
+                               foreach (TypeContainer tc in type_container_resolve_order)
+                                       TypeManager.CheckStructCycles (tc, seen);
+                       }
+               }
+
+               //
+               // A generic hook delegate
+               //
+               public delegate void Hook ();
+
+               //
+               // A hook invoked when the code has been generated.
+               //
+               public static event Hook EmitCodeHook;
+
+               //
+               // DefineTypes is used to fill in the members of each type.
+               //
+               static public void DefineTypes ()
+               {
+                       TypeContainer root = Tree.Types;
+
+                       if (attribute_types != null)
+                               foreach (TypeContainer tc in attribute_types)
+                                       tc.Define ();
+
+                       if (type_container_resolve_order != null){
+                               foreach (TypeContainer tc in type_container_resolve_order) {
+                                       // When compiling corlib, these types have already been
+                                       // populated from BootCorlib_PopulateCoreTypes ().
+                                       if (!RootContext.StdLib &&
+                                           ((tc.Name == "System.Object") ||
+                                            (tc.Name == "System.Attribute") ||
+                                            (tc.Name == "System.ValueType")))
+                                               continue;
+
+                                       if ((tc.ModFlags & Modifiers.NEW) == 0)
+                                               tc.Define ();
+                               }
+                       }
+
+                       ArrayList delegates = root.Delegates;
+                       if (delegates != null){
+                               foreach (Delegate d in delegates)
+                                       if ((d.ModFlags & Modifiers.NEW) == 0)
+                                               d.Define ();
+                       }
+
+                       ArrayList enums = root.Enums;
+                       if (enums != null){
+                               foreach (Enum en in enums)
+                                       if ((en.ModFlags & Modifiers.NEW) == 0)
+                                               en.Define ();
+                       }
+               }
+
+               static public void EmitCode ()
+               {
+                       if (attribute_types != null)
+                               foreach (TypeContainer tc in attribute_types)
+                                       tc.EmitType ();
+
+                       CodeGen.Assembly.Emit (Tree.Types);
+                       CodeGen.Module.Emit (Tree.Types);
+                        
+                       if (Tree.Types.Enums != null) {
+                               foreach (Enum e in Tree.Types.Enums)
+                                       e.Emit ();
+                       }
+
+                       if (type_container_resolve_order != null) {
+                               foreach (TypeContainer tc in type_container_resolve_order)
+                                       tc.EmitType ();
+                       }
+                       
+                       if (Tree.Types.Delegates != null) {
+                               foreach (Delegate d in Tree.Types.Delegates)
+                                       d.Emit ();
+                       }                       
+                       //
+                       // Run any hooks after all the types have been defined.
+                       // This is used to create nested auxiliary classes for example
+                       //
+
+                       if (EmitCodeHook != null)
+                               EmitCodeHook ();
+               }
+               
+               //
+               // Public Field, used to track which method is the public entry
+               // point.
+               //
+               static public MethodInfo EntryPoint;
+
+                //
+                // Track the location of the entry point.
+                //
+                static public Location EntryPointLocation;
+
+               //
+               // These are used to generate unique names on the structs and fields.
+               //
+               static int field_count;
+               
+               //
+               // Makes an initialized struct, returns the field builder that
+               // references the data.  Thanks go to Sergey Chaban for researching
+               // how to do this.  And coming up with a shorter mechanism than I
+               // was able to figure out.
+               //
+               // This works but makes an implicit public struct $ArrayType$SIZE and
+               // makes the fields point to it.  We could get more control if we did
+               // use instead:
+               //
+               // 1. DefineNestedType on the impl_details_class with our struct.
+               //
+               // 2. Define the field on the impl_details_class
+               //
+               static public FieldBuilder MakeStaticData (byte [] data)
+               {
+                       FieldBuilder fb;
+                       
+                       if (impl_details_class == null){
+                               impl_details_class = CodeGen.Module.Builder.DefineType (
+                                       "<PrivateImplementationDetails>",
+                                        TypeAttributes.NotPublic,
+                                        TypeManager.object_type);
+                                
+                               RegisterHelperClass (impl_details_class);
+                       }
+
+                       fb = impl_details_class.DefineInitializedData (
+                               "$$field-" + (field_count++), data,
+                               FieldAttributes.Static | FieldAttributes.Assembly);
+                       
+                       return fb;
+               }
+       }
+}
+             
+
diff --git a/mcs/bmcs/sample-hello.cs b/mcs/bmcs/sample-hello.cs
new file mode 100644 (file)
index 0000000..af2ea14
--- /dev/null
@@ -0,0 +1,29 @@
+using System;
+using Generics;
+
+namespace Test
+{
+       public class Bar : Foo
+       {
+               public void Hello (Stack<int> stack)
+               {
+                       Console.WriteLine ("Hello Generic World!");
+                       Console.WriteLine (stack);
+                       Console.WriteLine (stack.GetType ());
+               }
+
+               public Stack<int> Test ()
+               {
+                       return Driver.int_stack;
+               }
+
+               public static void Main ()
+               {
+                       Foo foo = new Bar ();
+                       Driver.Init (foo);
+                       Stack<int> a = Driver.int_stack;
+                       Console.WriteLine ("STACK: {0}", a);
+                       foo.Hello (a);
+               }
+       }
+}
diff --git a/mcs/bmcs/statement.cs b/mcs/bmcs/statement.cs
new file mode 100644 (file)
index 0000000..44fd3cc
--- /dev/null
@@ -0,0 +1,4728 @@
+//
+// statement.cs: Statement representation for the IL tree.
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//   Martin Baulig (martin@ximian.com)
+//
+// (C) 2001, 2002, 2003 Ximian, Inc.
+// (C) 2003, 2004 Novell, Inc.
+//
+
+using System;
+using System.Text;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Diagnostics;
+
+namespace Mono.CSharp {
+
+       using System.Collections;
+       
+       public abstract class Statement {
+               public Location loc;
+               
+               /// <summary>
+               /// Resolves the statement, true means that all sub-statements
+               /// did resolve ok.
+               //  </summary>
+               public virtual bool Resolve (EmitContext ec)
+               {
+                       return true;
+               }
+               
+               /// <summary>
+               ///   We already know that the statement is unreachable, but we still
+               ///   need to resolve it to catch errors.
+               /// </summary>
+               public virtual bool ResolveUnreachable (EmitContext ec, bool warn)
+               {
+                       //
+                       // This conflicts with csc's way of doing this, but IMHO it's
+                       // the right thing to do.
+                       //
+                       // If something is unreachable, we still check whether it's
+                       // correct.  This means that you cannot use unassigned variables
+                       // in unreachable code, for instance.
+                       //
+
+                       if (warn && (RootContext.WarningLevel >= 2))
+                               Report.Warning (162, loc, "Unreachable code detected");
+
+                       ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
+                       bool ok = Resolve (ec);
+                       ec.KillFlowBranching ();
+
+                       return ok;
+               }
+               
+               protected void CheckObsolete (Type type)
+               {
+                       ObsoleteAttribute obsolete_attr = AttributeTester.GetObsoleteAttribute (type);
+                       if (obsolete_attr == null)
+                               return;
+
+                       AttributeTester.Report_ObsoleteMessage (obsolete_attr, type.FullName, loc);
+               }
+               
+               /// <summary>
+               ///   Return value indicates whether all code paths emitted return.
+               /// </summary>
+               protected abstract void DoEmit (EmitContext ec);
+
+               /// <summary>
+               ///   Utility wrapper routine for Error, just to beautify the code
+               /// </summary>
+               public void Error (int error, string format, params object[] args)
+               {
+                       Error (error, String.Format (format, args));
+               }
+               
+               public void Error (int error, string s)
+               {
+                       if (!Location.IsNull (loc))
+                               Report.Error (error, loc, s);
+                               else
+                               Report.Error (error, s);
+               }
+
+               /// <summary>
+               ///   Return value indicates whether all code paths emitted return.
+               /// </summary>
+               public virtual void Emit (EmitContext ec)
+               {
+                       ec.Mark (loc, true);
+                       DoEmit (ec);
+               }
+       }
+
+       public sealed class EmptyStatement : Statement {
+               
+               private EmptyStatement () {}
+               
+               public static readonly EmptyStatement Value = new EmptyStatement ();
+               
+               public override bool Resolve (EmitContext ec)
+               {
+                       return true;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+               }
+       }
+       
+       public class If : Statement {
+               Expression expr;
+               public Statement TrueStatement;
+               public Statement FalseStatement;
+               
+               bool is_true_ret;
+               
+               public If (Expression expr, Statement trueStatement, Location l)
+               {
+                       this.expr = expr;
+                       TrueStatement = trueStatement;
+                       loc = l;
+               }
+
+               public If (Expression expr,
+                          Statement trueStatement,
+                          Statement falseStatement,
+                          Location l)
+               {
+                       this.expr = expr;
+                       TrueStatement = trueStatement;
+                       FalseStatement = falseStatement;
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       Report.Debug (1, "START IF BLOCK", loc);
+
+                       expr = Expression.ResolveBoolean (ec, expr, loc);
+                       if (expr == null){
+                               return false;
+                       }
+                       
+                       //
+                       // Dead code elimination
+                       //
+                       if (expr is BoolConstant){
+                               bool take = ((BoolConstant) expr).Value;
+
+                               if (take){
+                                       if (!TrueStatement.Resolve (ec))
+                                               return false;
+
+                                       if ((FalseStatement != null) &&
+                                           !FalseStatement.ResolveUnreachable (ec, true))
+                                               return false;
+                                       FalseStatement = null;
+                               } else {
+                                       if (!TrueStatement.ResolveUnreachable (ec, true))
+                                               return false;
+                                       TrueStatement = null;
+                       
+                                       if ((FalseStatement != null) &&
+                                           !FalseStatement.Resolve (ec))
+                               return false;
+                       }
+
+                               return true;
+                       }
+                       
+                       ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc);
+                       
+                       bool ok = TrueStatement.Resolve (ec);
+
+                       is_true_ret = ec.CurrentBranching.CurrentUsageVector.Reachability.IsUnreachable;
+
+                       ec.CurrentBranching.CreateSibling ();
+
+                       if ((FalseStatement != null) && !FalseStatement.Resolve (ec))
+                               ok = false;
+                                       
+                       ec.EndFlowBranching ();
+
+                       Report.Debug (1, "END IF BLOCK", loc);
+
+                       return ok;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       Label false_target = ig.DefineLabel ();
+                       Label end;
+
+                       //
+                       // If we're a boolean expression, Resolve() already
+                       // eliminated dead code for us.
+                       //
+                       if (expr is BoolConstant){
+                               bool take = ((BoolConstant) expr).Value;
+
+                               if (take)
+                                       TrueStatement.Emit (ec);
+                               else if (FalseStatement != null)
+                                               FalseStatement.Emit (ec);
+
+                                               return;
+                                       }
+                       
+                       expr.EmitBranchable (ec, false_target, false);
+
+                       TrueStatement.Emit (ec);
+
+                       if (FalseStatement != null){
+                               bool branch_emitted = false;
+                               
+                               end = ig.DefineLabel ();
+                               if (!is_true_ret){
+                                       ig.Emit (OpCodes.Br, end);
+                                       branch_emitted = true;
+                               }
+
+                               ig.MarkLabel (false_target);
+                               FalseStatement.Emit (ec);
+
+                               if (branch_emitted)
+                                       ig.MarkLabel (end);
+                       } else {
+                               ig.MarkLabel (false_target);
+                       }
+               }
+       }
+
+       public class Do : Statement {
+               public Expression expr;
+               public readonly Statement  EmbeddedStatement;
+               bool infinite;
+               
+               public Do (Statement statement, Expression boolExpr, Location l)
+               {
+                       expr = boolExpr;
+                       EmbeddedStatement = statement;
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       bool ok = true;
+
+                       ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
+
+                       if (!EmbeddedStatement.Resolve (ec))
+                               ok = false;
+
+                       expr = Expression.ResolveBoolean (ec, expr, loc);
+                       if (expr == null)
+                               ok = false;
+                       else if (expr is BoolConstant){
+                               bool res = ((BoolConstant) expr).Value;
+
+                               if (res)
+                                       infinite = true;
+                       }
+
+                       ec.CurrentBranching.Infinite = infinite;
+                       ec.EndFlowBranching ();
+
+                       return ok;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       Label loop = ig.DefineLabel ();
+                       Label old_begin = ec.LoopBegin;
+                       Label old_end = ec.LoopEnd;
+                       
+                       ec.LoopBegin = ig.DefineLabel ();
+                       ec.LoopEnd = ig.DefineLabel ();
+                               
+                       ig.MarkLabel (loop);
+                       EmbeddedStatement.Emit (ec);
+                       ig.MarkLabel (ec.LoopBegin);
+
+                       //
+                       // Dead code elimination
+                       //
+                       if (expr is BoolConstant){
+                               bool res = ((BoolConstant) expr).Value;
+
+                               if (res)
+                                       ec.ig.Emit (OpCodes.Br, loop); 
+                       } else
+                               expr.EmitBranchable (ec, loop, true);
+                       
+                       ig.MarkLabel (ec.LoopEnd);
+
+                       ec.LoopBegin = old_begin;
+                       ec.LoopEnd = old_end;
+               }
+       }
+
+       public class While : Statement {
+               public Expression expr;
+               public readonly Statement Statement;
+               bool infinite, empty;
+               
+               public While (Expression boolExpr, Statement statement, Location l)
+               {
+                       this.expr = boolExpr;
+                       Statement = statement;
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       bool ok = true;
+
+                       expr = Expression.ResolveBoolean (ec, expr, loc);
+                       if (expr == null)
+                               return false;
+
+                       //
+                       // Inform whether we are infinite or not
+                       //
+                       if (expr is BoolConstant){
+                               BoolConstant bc = (BoolConstant) expr;
+
+                               if (bc.Value == false){
+                                       if (!Statement.ResolveUnreachable (ec, true))
+                                               return false;
+                                       empty = true;
+                                       return true;
+                               } else
+                                       infinite = true;
+                       }
+
+                       ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
+
+                       if (!Statement.Resolve (ec))
+                               ok = false;
+
+                               ec.CurrentBranching.Infinite = infinite;
+                               ec.EndFlowBranching ();
+
+                       return ok;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       if (empty)
+                               return;
+
+                       ILGenerator ig = ec.ig;
+                       Label old_begin = ec.LoopBegin;
+                       Label old_end = ec.LoopEnd;
+                       
+                       ec.LoopBegin = ig.DefineLabel ();
+                       ec.LoopEnd = ig.DefineLabel ();
+
+                       //
+                       // Inform whether we are infinite or not
+                       //
+                       if (expr is BoolConstant){
+                               ig.MarkLabel (ec.LoopBegin);
+                               Statement.Emit (ec);
+                               ig.Emit (OpCodes.Br, ec.LoopBegin);
+                                       
+                               //
+                               // Inform that we are infinite (ie, `we return'), only
+                               // if we do not `break' inside the code.
+                               //
+                               ig.MarkLabel (ec.LoopEnd);
+                       } else {
+                               Label while_loop = ig.DefineLabel ();
+
+                               ig.Emit (OpCodes.Br, ec.LoopBegin);
+                               ig.MarkLabel (while_loop);
+
+                               Statement.Emit (ec);
+                       
+                               ig.MarkLabel (ec.LoopBegin);
+
+                               expr.EmitBranchable (ec, while_loop, true);
+                               
+                               ig.MarkLabel (ec.LoopEnd);
+                       }       
+
+                       ec.LoopBegin = old_begin;
+                       ec.LoopEnd = old_end;
+               }
+       }
+
+       public class For : Statement {
+               Expression Test;
+               readonly Statement InitStatement;
+               readonly Statement Increment;
+               readonly Statement Statement;
+               bool infinite, empty;
+               
+               public For (Statement initStatement,
+                           Expression test,
+                           Statement increment,
+                           Statement statement,
+                           Location l)
+               {
+                       InitStatement = initStatement;
+                       Test = test;
+                       Increment = increment;
+                       Statement = statement;
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       bool ok = true;
+
+                       if (InitStatement != null){
+                               if (!InitStatement.Resolve (ec))
+                                       ok = false;
+                       }
+
+                       if (Test != null){
+                               Test = Expression.ResolveBoolean (ec, Test, loc);
+                               if (Test == null)
+                                       ok = false;
+                               else if (Test is BoolConstant){
+                                       BoolConstant bc = (BoolConstant) Test;
+
+                                       if (bc.Value == false){
+                                               if (!Statement.ResolveUnreachable (ec, true))
+                                                       return false;
+                                               if ((Increment != null) &&
+                                                   !Increment.ResolveUnreachable (ec, false))
+                                                       return false;
+                                               empty = true;
+                                               return true;
+                                       } else
+                                               infinite = true;
+                               }
+                       } else
+                               infinite = true;
+
+                       ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
+                       if (!infinite)
+                               ec.CurrentBranching.CreateSibling ();
+
+                       if (!Statement.Resolve (ec))
+                               ok = false;
+
+                       if (Increment != null){
+                               if (!Increment.Resolve (ec))
+                                       ok = false;
+                       }
+
+                               ec.CurrentBranching.Infinite = infinite;
+                               ec.EndFlowBranching ();
+
+                       return ok;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       if (empty)
+                               return;
+
+                       ILGenerator ig = ec.ig;
+                       Label old_begin = ec.LoopBegin;
+                       Label old_end = ec.LoopEnd;
+                       Label loop = ig.DefineLabel ();
+                       Label test = ig.DefineLabel ();
+                       
+                       if (InitStatement != null && InitStatement != EmptyStatement.Value)
+                                       InitStatement.Emit (ec);
+
+                       ec.LoopBegin = ig.DefineLabel ();
+                       ec.LoopEnd = ig.DefineLabel ();
+
+                       ig.Emit (OpCodes.Br, test);
+                       ig.MarkLabel (loop);
+                       Statement.Emit (ec);
+
+                       ig.MarkLabel (ec.LoopBegin);
+                       if (Increment != EmptyStatement.Value)
+                               Increment.Emit (ec);
+
+                       ig.MarkLabel (test);
+                       //
+                       // If test is null, there is no test, and we are just
+                       // an infinite loop
+                       //
+                       if (Test != null){
+                               //
+                               // The Resolve code already catches the case for
+                               // Test == BoolConstant (false) so we know that
+                               // this is true
+                               //
+                               if (Test is BoolConstant)
+                                       ig.Emit (OpCodes.Br, loop);
+                               else
+                                       Test.EmitBranchable (ec, loop, true);
+                               
+                       } else
+                               ig.Emit (OpCodes.Br, loop);
+                       ig.MarkLabel (ec.LoopEnd);
+
+                       ec.LoopBegin = old_begin;
+                       ec.LoopEnd = old_end;
+               }
+       }
+       
+       public class StatementExpression : Statement {
+               public ExpressionStatement expr;
+               
+               public StatementExpression (ExpressionStatement expr, Location l)
+               {
+                       this.expr = expr;
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       expr = expr.ResolveStatement (ec);
+                       return expr != null;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       expr.EmitStatement (ec);
+               }
+
+               public override string ToString ()
+               {
+                       return "StatementExpression (" + expr + ")";
+               }
+       }
+
+       /// <summary>
+       ///   Implements the return statement
+       /// </summary>
+       public class Return : Statement {
+               public Expression Expr;
+               
+               public Return (Expression expr, Location l)
+               {
+                       Expr = expr;
+                       loc = l;
+               }
+
+               bool in_exc;
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       if (ec.ReturnType == null){
+                       if (Expr != null){
+                                       if (ec.CurrentAnonymousMethod != null){
+                                               Report.Error (1662, loc, String.Format (
+                                                       "Anonymous method could not be converted to delegate " +
+                                                       "since the return value does not match the delegate value"));
+                                       }
+                                       Error (127, "Return with a value not allowed here");
+                                       return false;
+                               }
+                       } else {
+                               if (Expr == null){
+                                       Error (126, "An object of type `{0}' is expected " +
+                                              "for the return statement",
+                                              TypeManager.CSharpName (ec.ReturnType));
+                                       return false;
+                               }
+
+                               Expr = Expr.Resolve (ec);
+                               if (Expr == null)
+                                       return false;
+
+                               if (Expr.Type != ec.ReturnType) {
+                                       Expr = Convert.ImplicitConversionRequired (
+                                               ec, Expr, ec.ReturnType, loc);
+                                       if (Expr == null)
+                                               return false;
+                               }
+                       }
+
+                       if (ec.InIterator){
+                               Error (-206, "Return statement not allowed inside iterators");
+                               return false;
+                       }
+                               
+                       FlowBranching.UsageVector vector = ec.CurrentBranching.CurrentUsageVector;
+
+                       if (ec.CurrentBranching.InTryOrCatch (true)) {
+                               ec.CurrentBranching.AddFinallyVector (vector);
+                               in_exc = true;
+                       } else if (ec.CurrentBranching.InFinally (true)) {
+                               Error (157, "Control can not leave the body of the finally block");
+                               return false;
+                       } else
+                               vector.CheckOutParameters (ec.CurrentBranching);
+
+                       if (in_exc)
+                               ec.NeedReturnLabel ();
+
+                       ec.CurrentBranching.CurrentUsageVector.Return ();
+                       return true;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       if (Expr != null) {
+                               Expr.Emit (ec);
+
+                               if (in_exc)
+                                       ec.ig.Emit (OpCodes.Stloc, ec.TemporaryReturn ());
+                       }
+
+                       if (in_exc)
+                               ec.ig.Emit (OpCodes.Leave, ec.ReturnLabel);
+                       else
+                               ec.ig.Emit (OpCodes.Ret);
+                       }
+               }
+
+       public class Goto : Statement {
+               string target;
+               Block block;
+               LabeledStatement label;
+               
+               public override bool Resolve (EmitContext ec)
+               {
+                       label = ec.CurrentBranching.LookupLabel (target, loc);
+                       if (label == null)
+                               return false;
+
+                       // If this is a forward goto.
+                       if (!label.IsDefined)
+                               label.AddUsageVector (ec.CurrentBranching.CurrentUsageVector);
+
+                       ec.CurrentBranching.CurrentUsageVector.Goto ();
+
+                       return true;
+               }
+               
+               public Goto (Block parent_block, string label, Location l)
+               {
+                       block = parent_block;
+                       loc = l;
+                       target = label;
+               }
+
+               public string Target {
+                       get {
+                               return target;
+                       }
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+                       Label l = label.LabelTarget (ec);
+                       ec.ig.Emit (OpCodes.Br, l);
+               }
+       }
+
+       public class LabeledStatement : Statement {
+               public readonly Location Location;
+               bool defined;
+               bool referenced;
+               Label label;
+
+               FlowBranching.UsageVector vectors;
+               
+               public LabeledStatement (string label_name, Location l)
+               {
+                       this.Location = l;
+               }
+
+               public Label LabelTarget (EmitContext ec)
+               {
+                       if (defined)
+                               return label;
+                       label = ec.ig.DefineLabel ();
+                       defined = true;
+
+                       return label;
+               }
+
+               public bool IsDefined {
+                       get {
+                               return defined;
+                       }
+               }
+
+               public bool HasBeenReferenced {
+                       get {
+                               return referenced;
+                       }
+               }
+
+               public void AddUsageVector (FlowBranching.UsageVector vector)
+               {
+                       vector = vector.Clone ();
+                       vector.Next = vectors;
+                       vectors = vector;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       ec.CurrentBranching.Label (vectors);
+
+                       referenced = true;
+
+                       return true;
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+                       LabelTarget (ec);
+                       ec.ig.MarkLabel (label);
+               }
+       }
+       
+
+       /// <summary>
+       ///   `goto default' statement
+       /// </summary>
+       public class GotoDefault : Statement {
+               
+               public GotoDefault (Location l)
+               {
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       ec.CurrentBranching.CurrentUsageVector.Goto ();
+                       return true;
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+                       if (ec.Switch == null){
+                               Report.Error (153, loc, "goto default is only valid in a switch statement");
+                               return;
+                       }
+
+                       if (!ec.Switch.GotDefault){
+                               Report.Error (159, loc, "No default target on switch statement");
+                               return;
+                       }
+                       ec.ig.Emit (OpCodes.Br, ec.Switch.DefaultTarget);
+               }
+       }
+
+       /// <summary>
+       ///   `goto case' statement
+       /// </summary>
+       public class GotoCase : Statement {
+               Expression expr;
+               SwitchLabel sl;
+               
+               public GotoCase (Expression e, Location l)
+               {
+                       expr = e;
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       if (ec.Switch == null){
+                               Report.Error (153, loc, "goto case is only valid in a switch statement");
+                               return false;
+                       }
+
+                       expr = expr.Resolve (ec);
+                       if (expr == null)
+                               return false;
+
+                       if (!(expr is Constant)){
+                               Report.Error (159, loc, "Target expression for goto case is not constant");
+                               return false;
+                       }
+
+                       object val = Expression.ConvertIntLiteral (
+                               (Constant) expr, ec.Switch.SwitchType, loc);
+
+                       if (val == null)
+                               return false;
+                                       
+                       sl = (SwitchLabel) ec.Switch.Elements [val];
+
+                       if (sl == null){
+                               Report.Error (
+                                       159, loc,
+                                       "No such label 'case " + val + "': for the goto case");
+                               return false;
+                       }
+
+                       ec.CurrentBranching.CurrentUsageVector.Goto ();
+                       return true;
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+                       ec.ig.Emit (OpCodes.Br, sl.GetILLabelCode (ec));
+               }
+       }
+       
+       public class Throw : Statement {
+               Expression expr;
+               
+               public Throw (Expression expr, Location l)
+               {
+                       this.expr = expr;
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       bool in_catch = ec.CurrentBranching.InCatch ();
+                       ec.CurrentBranching.CurrentUsageVector.Throw ();
+
+                       if (expr != null){
+                               expr = expr.Resolve (ec);
+                               if (expr == null)
+                                       return false;
+
+                               ExprClass eclass = expr.eclass;
+
+                               if (!(eclass == ExprClass.Variable || eclass == ExprClass.PropertyAccess ||
+                                     eclass == ExprClass.Value || eclass == ExprClass.IndexerAccess)) {
+                                       expr.Error_UnexpectedKind ("value, variable, property or indexer access ", loc);
+                                       return false;
+                               }
+
+                               Type t = expr.Type;
+                               
+                               if ((t != TypeManager.exception_type) &&
+                                   !t.IsSubclassOf (TypeManager.exception_type) &&
+                                   !(expr is NullLiteral)) {
+                                       Error (155,
+                                                     "The type caught or thrown must be derived " +
+                                                     "from System.Exception");
+                                       return false;
+                               }
+                       } else if (!in_catch) {
+                               Error (156,
+                                      "A throw statement with no argument is only " +
+                                      "allowed in a catch clause");
+                               return false;
+                       }
+
+                       return true;
+               }
+                       
+               protected override void DoEmit (EmitContext ec)
+               {
+                       if (expr == null)
+                                       ec.ig.Emit (OpCodes.Rethrow);
+                               else {
+                       expr.Emit (ec);
+
+                       ec.ig.Emit (OpCodes.Throw);
+               }
+       }
+       }
+
+       public class Break : Statement {
+               
+               public Break (Location l)
+               {
+                       loc = l;
+               }
+
+               bool crossing_exc;
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       if (!ec.CurrentBranching.InLoop () && !ec.CurrentBranching.InSwitch ()){
+                               Error (139, "No enclosing loop or switch to continue to");
+                               return false;
+                       } else if (ec.CurrentBranching.InFinally (false)) {
+                               Error (157, "Control can not leave the body of the finally block");
+                               return false;
+                       } else if (ec.CurrentBranching.InTryOrCatch (false))
+                               ec.CurrentBranching.AddFinallyVector (
+                                       ec.CurrentBranching.CurrentUsageVector);
+                       else if (ec.CurrentBranching.InLoop ())
+                               ec.CurrentBranching.AddBreakVector (
+                                       ec.CurrentBranching.CurrentUsageVector);
+
+                       crossing_exc = ec.CurrentBranching.BreakCrossesTryCatchBoundary ();
+
+                       if (!crossing_exc)
+                               ec.NeedReturnLabel ();
+
+                       ec.CurrentBranching.CurrentUsageVector.Break ();
+                       return true;
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       if (crossing_exc)
+                               ig.Emit (OpCodes.Leave, ec.LoopEnd);
+                       else {
+                               ig.Emit (OpCodes.Br, ec.LoopEnd);
+               }
+       }
+       }
+
+       public class Continue : Statement {
+               
+               public Continue (Location l)
+               {
+                       loc = l;
+               }
+
+               bool crossing_exc;
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       if (!ec.CurrentBranching.InLoop () && !ec.CurrentBranching.InSwitch ()){
+                               Error (139, "No enclosing loop to continue to");
+                               return false;
+                       } else if (ec.CurrentBranching.InFinally (false)) {
+                               Error (157, "Control can not leave the body of the finally block");
+                               return false;
+                       } else if (ec.CurrentBranching.InTryOrCatch (false))
+                               ec.CurrentBranching.AddFinallyVector (ec.CurrentBranching.CurrentUsageVector);
+
+                       crossing_exc = ec.CurrentBranching.BreakCrossesTryCatchBoundary ();
+
+                       ec.CurrentBranching.CurrentUsageVector.Goto ();
+                       return true;
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+                       Label begin = ec.LoopBegin;
+                       
+                       if (crossing_exc)
+                               ec.ig.Emit (OpCodes.Leave, begin);
+                       else
+                               ec.ig.Emit (OpCodes.Br, begin);
+               }
+       }
+
+       //
+       // The information about a user-perceived local variable
+       //
+       public class LocalInfo {
+               public Expression Type;
+
+               //
+               // Most of the time a variable will be stored in a LocalBuilder
+               //
+               // But sometimes, it will be stored in a field (variables that have been
+               // hoisted by iterators or by anonymous methods).  The context of the field will
+               // be stored in the EmitContext
+               //
+               //
+               public LocalBuilder LocalBuilder;
+               public FieldBuilder FieldBuilder;
+
+               public Type VariableType;
+               public readonly string Name;
+               public readonly Location Location;
+               public readonly Block Block;
+
+               public VariableInfo VariableInfo;
+
+               enum Flags : byte {
+                       Used = 1,
+                       ReadOnly = 2,
+                       Pinned = 4,
+                       IsThis = 8,
+                       Captured = 16,
+                       AddressTaken = 32
+               }
+
+               Flags flags;
+
+               public LocalInfo (Expression type, string name, Block block, Location l)
+               {
+                       Type = type;
+                       Name = name;
+                       Block = block;
+                       Location = l;
+               }
+
+               public LocalInfo (TypeContainer tc, Block block, Location l)
+               {
+                       VariableType = tc.TypeBuilder;
+                       Block = block;
+                       Location = l;
+               }
+
+               public bool IsThisAssigned (EmitContext ec, Location loc)
+               {
+                       if (VariableInfo == null)
+                               throw new Exception ();
+
+                       if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo))
+                               return true;
+
+                       return VariableInfo.TypeInfo.IsFullyInitialized (ec.CurrentBranching, VariableInfo, loc);
+               }
+
+               public bool IsAssigned (EmitContext ec)
+               {
+                       if (VariableInfo == null)
+                               throw new Exception ();
+
+                       return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo);
+               }
+
+               public bool Resolve (EmitContext ec)
+               {
+                       if (VariableType == null) {
+                               TypeExpr texpr = Type.ResolveAsTypeTerminal (ec);
+                               if (texpr == null)
+                                       return false;
+                               
+                               VariableType = texpr.Type;
+                       }
+
+                       if (VariableType == TypeManager.void_type) {
+                               Report.Error (1547, Location,
+                                             "Keyword 'void' cannot be used in this context");
+                               return false;
+                       }
+
+                       if (VariableType.IsAbstract && VariableType.IsSealed) {
+                               Report.Error (723, Location, "Cannot declare variable of static type '{0}'", TypeManager.CSharpName (VariableType));
+                               return false;
+                       }
+// TODO: breaks the build
+//                     if (VariableType.IsPointer && !ec.InUnsafe)
+//                             Expression.UnsafeError (Location);
+
+                       return true;
+               }
+
+               //
+               // Whether the variable is Fixed (because its Pinned or its a value type)
+               //
+               public bool IsFixed {
+                       get {
+                               if (((flags & Flags.Pinned) != 0) || TypeManager.IsValueType (VariableType))
+                                       return true;
+                               
+                               return false;
+                       }
+               }
+               
+               public bool IsCaptured {
+                       get {
+                               return (flags & Flags.Captured) != 0;
+                       }
+
+                       set {
+                               flags |= Flags.Captured;
+                       }
+               }
+
+               public bool AddressTaken {
+                       get {
+                               return (flags & Flags.AddressTaken) != 0;
+                       }
+
+                       set {
+                               flags |= Flags.AddressTaken;
+                       }
+               }
+
+               public override string ToString ()
+               {
+                       return String.Format ("LocalInfo ({0},{1},{2},{3})",
+                                             Name, Type, VariableInfo, Location);
+               }
+
+               public bool Used {
+                       get {
+                               return (flags & Flags.Used) != 0;
+                       }
+                       set {
+                               flags = value ? (flags | Flags.Used) : (unchecked (flags & ~Flags.Used));
+                       }
+               }
+
+               public bool ReadOnly {
+                       get {
+                               return (flags & Flags.ReadOnly) != 0;
+                       }
+                       set {
+                               flags = value ? (flags | Flags.ReadOnly) : (unchecked (flags & ~Flags.ReadOnly));
+                       }
+               }
+
+               //
+               // Whether the variable is pinned, if Pinned the variable has been 
+               // allocated in a pinned slot with DeclareLocal.
+               //
+               public bool Pinned {
+                       get {
+                               return (flags & Flags.Pinned) != 0;
+                       }
+                       set {
+                               flags = value ? (flags | Flags.Pinned) : (flags & ~Flags.Pinned);
+                       }
+               }
+
+               public bool IsThis {
+                       get {
+                               return (flags & Flags.IsThis) != 0;
+                       }
+                       set {
+                               flags = value ? (flags | Flags.IsThis) : (flags & ~Flags.IsThis);
+                       }
+               }
+       }
+               
+       /// <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.
+       ///
+       ///   Top-level blocks derive from Block, and they are called ToplevelBlock
+       ///   they contain extra information that is not necessary on normal blocks.
+       /// </remarks>
+       public class Block : Statement {
+               public Block    Parent;
+               public readonly Location  StartLocation;
+               public Location           EndLocation = Location.Null;
+
+               [Flags]
+               public enum Flags {
+                       Implicit  = 1,
+                       Unchecked = 2,
+                       BlockUsed = 4,
+                       VariablesInitialized = 8,
+                       HasRet = 16,
+                       IsDestructor = 32,
+                       HasVarargs = 64,
+                       IsToplevel = 128,
+                       Unsafe = 256
+               }
+               Flags flags;
+
+               public bool Implicit {
+                       get {
+                               return (flags & Flags.Implicit) != 0;
+                       }
+               }
+
+               public bool Unchecked {
+                       get {
+                               return (flags & Flags.Unchecked) != 0;
+                       }
+                       set {
+                               flags |= Flags.Unchecked;
+                       }
+               }
+
+               public bool Unsafe {
+                       get {
+                               return (flags & Flags.Unsafe) != 0;
+                       }
+                       set {
+                               flags |= Flags.Unsafe;
+                       }
+               }
+
+               public bool HasVarargs {
+                       get {
+                               if (Parent != null)
+                                       return Parent.HasVarargs;
+                               else
+                                       return (flags & Flags.HasVarargs) != 0;
+                       }
+                       set {
+                               flags |= Flags.HasVarargs;
+                       }
+               }
+
+               //
+               // The statements in this block
+               //
+               public ArrayList statements;
+               int num_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.
+               //
+               Hashtable labels;
+
+               //
+               // Keeps track of (name, type) pairs
+               //
+               Hashtable variables;
+
+               //
+               // Keeps track of constants
+               Hashtable constants;
+
+               //
+               // The parameters for the block, this is only needed on the toplevel block really
+               // TODO: move `parameters' into ToplevelBlock
+               Parameters parameters;
+               
+               //
+               // If this is a switch section, the enclosing switch block.
+               //
+               Block switch_block;
+
+               protected static int id;
+
+               int this_id;
+               
+               public Block (Block parent)
+                       : this (parent, (Flags) 0, Location.Null, Location.Null)
+               { }
+
+               public Block (Block parent, Flags flags)
+                       : this (parent, flags, Location.Null, Location.Null)
+               { }
+
+               public Block (Block parent, Flags flags, Parameters parameters)
+                       : this (parent, flags, parameters, Location.Null, Location.Null)
+               { }
+
+               public Block (Block parent, Location start, Location end)
+                       : this (parent, (Flags) 0, start, end)
+               { }
+
+               public Block (Block parent, Parameters parameters, Location start, Location end)
+                       : this (parent, (Flags) 0, parameters, start, end)
+               { }
+
+               public Block (Block parent, Flags flags, Location start, Location end)
+                       : this (parent, flags, Parameters.EmptyReadOnlyParameters, start, end)
+               { }
+
+               public Block (Block parent, Flags flags, Parameters parameters,
+                             Location start, Location end)
+               {
+                       if (parent != null)
+                               parent.AddChild (this);
+                       
+                       this.Parent = parent;
+                       this.flags = flags;
+                       this.parameters = parameters;
+                       this.StartLocation = start;
+                       this.EndLocation = end;
+                       this.loc = start;
+                       this_id = id++;
+                       statements = new ArrayList ();
+
+                       if (parent != null && Implicit) {
+                               if (parent.child_variable_names == null)
+                                       parent.child_variable_names = new Hashtable();
+                               // share with parent
+                               child_variable_names = parent.child_variable_names;
+                       }
+                               
+               }
+
+               public Block CreateSwitchBlock (Location start)
+               {
+                       Block new_block = new Block (this, start, start);
+                       new_block.switch_block = this;
+                       return new_block;
+               }
+
+               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, Location loc)
+               {
+                       if (switch_block != null)
+                               return switch_block.AddLabel (name, target, loc);
+
+                       Block cur = this;
+                       while (cur != null) {
+                               if (cur.DoLookupLabel (name) != null) {
+                                       Report.Error (
+                                               140, loc, "The label '{0}' is a duplicate",
+                                               name);
+                                       return false;
+                               }
+
+                               if (!Implicit)
+                                       break;
+
+                               cur = cur.Parent;
+                       }
+
+                       while (cur != null) {
+                               if (cur.DoLookupLabel (name) != null) {
+                                       Report.Error (
+                                               158, loc,
+                                               "The label '{0}' shadows another label " +
+                                               "by the same name in a containing scope.",
+                                               name);
+                                       return false;
+                               }
+
+                               if (children != null) {
+                                       foreach (Block b in children) {
+                                               LabeledStatement s = b.DoLookupLabel (name);
+                                               if (s == null)
+                                                       continue;
+
+                                               Report.Error (
+                                                       158, s.Location,
+                                                       "The label '{0}' shadows another " +
+                                                       "label by the same name in a " +
+                                                       "containing scope.",
+                                                       name);
+                                               return false;
+                                       }
+                               }
+
+
+                               cur = cur.Parent;
+                       }
+
+                       if (labels == null)
+                               labels = new Hashtable ();
+
+                       labels.Add (name, target);
+                       return true;
+               }
+
+               public LabeledStatement LookupLabel (string name)
+               {
+                       LabeledStatement s = DoLookupLabel (name);
+                       if (s != null)
+                               return s;
+
+                       if (children == null)
+                               return null;
+
+                       foreach (Block child in children) {
+                               if (!child.Implicit)
+                                       continue;
+
+                               s = child.LookupLabel (name);
+                               if (s != null)
+                                       return s;
+                       }
+
+                       return null;
+               }
+
+               LabeledStatement DoLookupLabel (string name)
+               {
+                       if (switch_block != null)
+                               return switch_block.LookupLabel (name);
+
+                       if (labels != null)
+                               if (labels.Contains (name))
+                                       return ((LabeledStatement) labels [name]);
+
+                       return null;
+               }
+
+               LocalInfo this_variable = null;
+
+               // <summary>
+               //   Returns the "this" instance variable of this block.
+               //   See AddThisVariable() for more information.
+               // </summary>
+               public LocalInfo 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 Hashtable ();
+
+                       child_variable_names [name] = null;
+               }
+
+               // <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 LocalInfo AddThisVariable (TypeContainer tc, Location l)
+               {
+                       if (this_variable != null)
+                               return this_variable;
+
+                       if (variables == null)
+                               variables = new Hashtable ();
+
+                       this_variable = new LocalInfo (tc, this, l);
+                       this_variable.Used = true;
+                       this_variable.IsThis = true;
+
+                       variables.Add ("this", this_variable);
+
+                       return this_variable;
+               }
+
+               public LocalInfo AddVariable (Expression type, string name, Parameters pars, Location l)
+               {
+                       if (variables == null)
+                               variables = new Hashtable ();
+
+                       LocalInfo vi = GetLocalInfo (name);
+                       if (vi != null) {
+                               if (vi.Block != this)
+                                       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 `parent or current' scope to " +
+                                                     "denote something else");
+                               else
+                                       Report.Error (128, 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;
+                               Parameter p = pars.GetParameterByName (name, out idx);
+                               if (p != null) {
+                                       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 `parent or current' scope to " +
+                                                     "denote something else");
+                                       return null;
+                               }
+                       }
+
+                       vi = new LocalInfo (type, name, this, l);
+
+                       variables.Add (name, vi);
+
+                       // Mark 'name' as "used by a child block" in every surrounding block
+                       Block cur = this;
+                       while (cur != null && cur.Implicit) 
+                               cur = cur.Parent;
+                       if (cur != null)
+                               for (Block par = cur.Parent; par != null; par = par.Parent)
+                                       par.AddChildVariableName (name);
+
+                       if ((flags & Flags.VariablesInitialized) != 0)
+                               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 Hashtable ();
+
+                       constants.Add (name, value);
+                       return true;
+               }
+
+               public Hashtable Variables {
+                       get {
+                               return variables;
+                       }
+               }
+
+               public LocalInfo GetLocalInfo (string name)
+               {
+                       for (Block b = this; b != null; b = b.Parent) {
+                               if (b.variables != null) {
+                                       LocalInfo ret = b.variables [name] as LocalInfo;
+                                       if (ret != null)
+                                               return ret;
+                               }
+                       }
+                       return null;
+               }
+
+               public Expression GetVariableType (string name)
+               {
+                       LocalInfo vi = GetLocalInfo (name);
+
+                       if (vi != null)
+                               return vi.Type;
+
+                       return null;
+               }
+
+               public Expression GetConstantExpression (string name)
+               {
+                       for (Block b = this; b != null; b = b.Parent) {
+                               if (b.constants != null) {
+                                       Expression ret = b.constants [name] as Expression;
+                                       if (ret != null)
+                                               return ret;
+                               }
+                       }
+                       return null;
+               }
+               
+               /// <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;
+               }
+               
+               //
+               // Returns a `ParameterReference' for the given name, or null if there
+               // is no such parameter
+               //
+               public ParameterReference GetParameterReference (string name, Location loc)
+               {
+                               Block b = this;
+
+                       do {
+                               Parameters pars = b.parameters;
+                               
+                               if (pars != null){
+                                       Parameter par;
+                                       int idx;
+                                       
+                                       par = pars.GetParameterByName (name, out idx);
+                                       if (par != null){
+                                               ParameterReference pr;
+
+                                               pr = new ParameterReference (pars, this, idx, name, loc);
+                                               return pr;
+                                       }
+                               }
+                                       b = b.Parent;
+                       } while (b != null);
+                       return null;
+                       }
+
+               //
+               // Whether the parameter named `name' is local to this block, 
+               // or false, if the parameter belongs to an encompassing block.
+               //
+               public bool IsLocalParameter (string name)
+               {
+                               Block b = this;
+                       int toplevel_count = 0;
+
+                       do {
+                               if (this is ToplevelBlock)
+                                       toplevel_count++;
+
+                               Parameters pars = b.parameters;
+                               if (pars != null){
+                                       if (pars.GetParameterByName (name) != null)
+                                               return true;
+                                       return false;
+                               }
+                               if (toplevel_count > 0)
+                                       return false;
+                                       b = b.Parent;
+                       } while (b != null);
+                       return false;
+                       }
+               
+               //
+               // Whether the `name' is a parameter reference
+               //
+               public bool IsParameterReference (string name)
+               {
+                       Block b = this;
+
+                       do {
+                               Parameters pars = b.parameters;
+                               
+                               if (pars != null)
+                                       if (pars.GetParameterByName (name) != null)
+                                               return true;
+                               b = b.Parent;
+                       } while (b != null);
+                       return false;
+               }
+
+               /// <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);
+                       flags |= Flags.BlockUsed;
+               }
+
+               public bool Used {
+                       get {
+                               return (flags & Flags.BlockUsed) != 0;
+                       }
+               }
+
+               public void Use ()
+               {
+                       flags |= Flags.BlockUsed;
+               }
+
+               public bool HasRet {
+                       get {
+                               return (flags & Flags.HasRet) != 0;
+                       }
+               }
+
+               public bool IsDestructor {
+                       get {
+                               return (flags & Flags.IsDestructor) != 0;
+                       }
+               }
+
+               public void SetDestructor ()
+               {
+                       flags |= Flags.IsDestructor;
+               }
+
+               VariableMap param_map, local_map;
+
+               public VariableMap ParameterMap {
+                       get {
+                               if ((flags & Flags.VariablesInitialized) == 0)
+                                       throw new Exception ("Variables have not been initialized yet");
+
+                               return param_map;
+                       }
+               }
+
+               public VariableMap LocalMap {
+                       get {
+                               if ((flags & Flags.VariablesInitialized) == 0)
+                                       throw new Exception ("Variables have not been initialized yet");
+
+                               return local_map;
+                       }
+               }
+
+               /// <summary>
+               ///   Emits the variable declarations and labels.
+               /// </summary>
+               /// <remarks>
+               ///   tc: is our typecontainer (to resolve type references)
+               ///   ig: is the code generator:
+               /// </remarks>
+               public void ResolveMeta (ToplevelBlock toplevel, EmitContext ec, InternalParameters ip)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       bool old_unsafe = ec.InUnsafe;
+
+                       // If some parent block was unsafe, we remain unsafe even if this block
+                       // isn't explicitly marked as such.
+                       ec.InUnsafe |= Unsafe;
+
+                       //
+                       // Compute the VariableMap's.
+                       //
+                       // Unfortunately, we don't know the type when adding variables with
+                       // AddVariable(), so we need to compute this info here.
+                       //
+
+                       LocalInfo[] locals;
+                       if (variables != null) {
+                               foreach (LocalInfo li in variables.Values)
+                                       li.Resolve (ec);
+
+                               locals = new LocalInfo [variables.Count];
+                               variables.Values.CopyTo (locals, 0);
+                       } else
+                               locals = new LocalInfo [0];
+
+                       if (Parent != null)
+                               local_map = new VariableMap (Parent.LocalMap, locals);
+                       else
+                               local_map = new VariableMap (locals);
+
+                       param_map = new VariableMap (ip);
+                       flags |= Flags.VariablesInitialized;
+
+                       bool old_check_state = ec.ConstantCheckState;
+                       ec.ConstantCheckState = (flags & Flags.Unchecked) == 0;
+                               
+                       //
+                       // Process this block variables
+                       //
+                       if (variables != null){
+                               foreach (DictionaryEntry de in variables){
+                                       string name = (string) de.Key;
+                                       LocalInfo vi = (LocalInfo) de.Value;
+                                       
+                                       if (vi.VariableType == null)
+                                               continue;
+
+                                       Type variable_type = vi.VariableType;
+
+                                       if (variable_type.IsPointer){
+                                               //
+                                               // Am not really convinced that this test is required (Microsoft does it)
+                                               // but the fact is that you would not be able to use the pointer variable
+                                               // *anyways*
+                                               //
+                                               if (!TypeManager.VerifyUnManaged (TypeManager.GetElementType (variable_type),
+                                                                                  vi.Location))
+                                                       continue;
+                                       }
+
+#if false
+                                       if (remap_locals)
+                                               vi.FieldBuilder = ec.MapVariable (name, vi.VariableType);
+                                       else if (vi.Pinned)
+                                               //
+                                               // This is needed to compile on both .NET 1.x and .NET 2.x
+                                               // the later introduced `DeclareLocal (Type t, bool pinned)'
+                                               //
+                                               vi.LocalBuilder = TypeManager.DeclareLocalPinned (ig, vi.VariableType);
+                                       else if (!vi.IsThis)
+                                               vi.LocalBuilder = ig.DeclareLocal (vi.VariableType);
+#endif
+
+                                       if (constants == null)
+                                               continue;
+
+                                       Expression cv = (Expression) constants [name];
+                                       if (cv == null)
+                                               continue;
+
+                                       ec.CurrentBlock = this;
+                                       Expression e = cv.Resolve (ec);
+                                       if (e == null)
+                                               continue;
+
+                                       Constant ce = e as Constant;
+                                       if (ce == null){
+                                               Report.Error (133, vi.Location,
+                                                             "The expression being assigned to `" +
+                                                             name + "' must be constant (" + e + ")");
+                                               continue;
+                                       }
+
+                                       if (e.Type != variable_type){
+                                               e = Const.ChangeType (vi.Location, ce, variable_type);
+                                               if (e == null)
+                                                       continue;
+                                       }
+
+                                       constants.Remove (name);
+                                       constants.Add (name, e);
+                               }
+                       }
+                       ec.ConstantCheckState = old_check_state;
+
+                       //
+                       // Now, handle the children
+                       //
+                       if (children != null){
+                               foreach (Block b in children)
+                                       b.ResolveMeta (toplevel, ec, ip);
+                       }
+                       ec.InUnsafe = old_unsafe;
+               }
+
+               //
+               // Emits the local variable declarations for a block
+               //
+               public void EmitMeta (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       if (variables != null){
+                               bool have_captured_vars = ec.HaveCapturedVariables ();
+                               bool remap_locals = ec.RemapToProxy;
+                               
+                               foreach (DictionaryEntry de in variables){
+                                       LocalInfo vi = (LocalInfo) de.Value;
+
+                                       if (have_captured_vars && ec.IsCaptured (vi))
+                                               continue;
+
+                                       if (remap_locals){
+                                               vi.FieldBuilder = ec.MapVariable (vi.Name, vi.VariableType);
+                                       } else {
+                                               if (vi.Pinned)
+                                                       //
+                                                       // This is needed to compile on both .NET 1.x and .NET 2.x
+                                                       // the later introduced `DeclareLocal (Type t, bool pinned)'
+                                                       //
+                                                       vi.LocalBuilder = TypeManager.DeclareLocalPinned (ig, vi.VariableType);
+                                               else if (!vi.IsThis)
+                                                       vi.LocalBuilder = ig.DeclareLocal (vi.VariableType);
+                                       }
+                               }
+                       }
+
+                       if (children != null){
+                               foreach (Block b in children)
+                                       b.EmitMeta (ec);
+                       }
+               }
+
+               void UsageWarning (FlowBranching.UsageVector vector)
+               {
+                       string name;
+                       
+                       if ((variables != null) && (RootContext.WarningLevel >= 3)) {
+                               foreach (DictionaryEntry de in variables){
+                                       LocalInfo vi = (LocalInfo) de.Value;
+                                       
+                                       if (vi.Used)
+                                               continue;
+                                       
+                                       name = (string) de.Key;
+                                               
+                                       if (vector.IsAssigned (vi.VariableInfo)){
+                                               Report.Warning (219, vi.Location, "The variable '{0}' is assigned but its value is never used", name);
+                                       } else {
+                                               Report.Warning (168, vi.Location, "The variable '{0}' is declared but never used", name);
+                                       }
+                               }
+                       }
+               }
+
+               bool unreachable_shown;
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       Block prev_block = ec.CurrentBlock;
+                       bool ok = true;
+
+                       int errors = Report.Errors;
+
+                       ec.CurrentBlock = this;
+                       ec.StartFlowBranching (this);
+
+                       Report.Debug (4, "RESOLVE BLOCK", StartLocation, ec.CurrentBranching);
+
+                       bool unreachable = false;
+
+                       int statement_count = statements.Count;
+                       for (int ix = 0; ix < statement_count; ix++){
+                               Statement s = (Statement) statements [ix];
+                               
+                               if (unreachable && !(s is LabeledStatement)) {
+                                       if (s == EmptyStatement.Value)
+                                               s.loc = EndLocation;
+
+                                       if (!s.ResolveUnreachable (ec, !unreachable_shown))
+                                               ok = false;
+
+                                       if (s != EmptyStatement.Value)
+                                               unreachable_shown = true;
+                                       else
+                                               s.loc = Location.Null;
+
+                                       statements [ix] = EmptyStatement.Value;
+                                       continue;
+                               }
+
+                               if (s.Resolve (ec) == false) {
+                                       ok = false;
+                                       statements [ix] = EmptyStatement.Value;
+                                       continue;
+                               }
+
+                               num_statements = ix + 1;
+
+                               if (s is LabeledStatement)
+                                       unreachable = false;
+                               else
+                                       unreachable = ec.CurrentBranching.CurrentUsageVector.Reachability.IsUnreachable;
+                       }
+
+                       Report.Debug (4, "RESOLVE BLOCK DONE", StartLocation,
+                                     ec.CurrentBranching, statement_count, num_statements);
+
+
+                       FlowBranching.UsageVector vector = ec.DoEndFlowBranching ();
+
+                       ec.CurrentBlock = prev_block;
+
+                       // 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) &&
+                           (vector.Reachability.Throws != FlowBranching.FlowReturns.Always) &&
+                           !this_variable.IsThisAssigned (ec, loc))
+                               ok = false;
+
+                       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");
+                       }
+
+                       Report.Debug (4, "RESOLVE BLOCK DONE #2", StartLocation, vector);
+
+                       if ((vector.Reachability.Returns == FlowBranching.FlowReturns.Always) ||
+                           (vector.Reachability.Throws == FlowBranching.FlowReturns.Always) ||
+                           (vector.Reachability.Reachable == FlowBranching.FlowReturns.Never))
+                               flags |= Flags.HasRet;
+
+                       if (ok && (errors == Report.Errors)) {
+                               if (RootContext.WarningLevel >= 3)
+                                       UsageWarning (vector);
+                       }
+
+                       return ok;
+               }
+               
+               public override bool ResolveUnreachable (EmitContext ec, bool warn)
+               {
+                       unreachable_shown = true;
+                       return base.ResolveUnreachable (ec, warn);
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       for (int ix = 0; ix < num_statements; ix++){
+                               Statement s = (Statement) statements [ix];
+
+                               // Check whether we are the last statement in a
+                               // top-level block.
+
+                               if ((Parent == null) && (ix+1 == num_statements))
+                                       ec.IsLastStatement = true;
+                               else
+                                       ec.IsLastStatement = false;
+
+                               s.Emit (ec);
+                       }
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+                       Block prev_block = ec.CurrentBlock;
+
+                       ec.CurrentBlock = this;
+
+                       bool emit_debug_info = (CodeGen.SymbolWriter != null);
+                       bool is_lexical_block = !Implicit && (Parent != null);
+
+                       if (emit_debug_info) {
+                               if (is_lexical_block)
+                                       ec.ig.BeginScope ();
+
+                               if (variables != null) {
+                                       foreach (DictionaryEntry de in variables) {
+                                               string name = (string) de.Key;
+                                               LocalInfo vi = (LocalInfo) de.Value;
+
+                                               if (vi.LocalBuilder == null)
+                                                       continue;
+
+                                               ec.DefineLocalVariable (name, vi.LocalBuilder);
+                                       }
+                               }
+                       }
+
+                       ec.Mark (StartLocation, true);
+                       DoEmit (ec);
+                       ec.Mark (EndLocation, true); 
+
+                       if (emit_debug_info && is_lexical_block)
+                               ec.ig.EndScope ();
+
+                       ec.CurrentBlock = prev_block;
+               }
+
+               public ToplevelBlock Toplevel {
+                       get {
+                               Block b = this;
+                               while (b.Parent != null){
+                                       if ((b.flags & Flags.IsToplevel) != 0)
+                                               break;
+                                       b = b.Parent;
+                               }
+
+                               return (ToplevelBlock) b;
+                       }
+       }
+
+       //
+               // Returns true if we ar ea child of `b'.
+               //
+               public bool IsChildOf (Block b)
+               {
+                       Block current = this;
+                       
+                       do {
+                               if (current.Parent == b)
+                                       return true;
+                               current = current.Parent;
+                       } while (current != null);
+                       return false;
+               }
+       }
+
+       //
+       // A toplevel block contains extra information, the split is done
+       // only to separate information that would otherwise bloat the more
+       // lightweight Block.
+       //
+       // In particular, this was introduced when the support for Anonymous
+       // Methods was implemented. 
+       // 
+       public class ToplevelBlock : Block {
+               //
+               // Pointer to the host of this anonymous method, or null
+               // if we are the topmost block
+               //
+               public ToplevelBlock Container;
+               CaptureContext capture_context;
+
+               Hashtable capture_contexts;
+
+               static int did = 0;
+               
+               int my_id = did++;
+
+                       
+               public void RegisterCaptureContext (CaptureContext cc)
+               {
+                       if (capture_contexts == null)
+                               capture_contexts = new Hashtable ();
+                       capture_contexts [cc] = cc;
+               }
+
+               public void CompleteContexts ()
+               {
+                       if (capture_contexts == null)
+                               return;
+
+                       foreach (CaptureContext cc in capture_contexts.Keys){
+                               cc.AdjustScopes ();
+                       }
+               }
+               
+               public CaptureContext ToplevelBlockCaptureContext {
+                       get {
+                               return capture_context;
+                       }
+               }
+               
+               //
+               // Parent is only used by anonymous blocks to link back to their
+               // parents
+               //
+               public ToplevelBlock (ToplevelBlock container, Parameters parameters, Location start) :
+                       base (null, Flags.IsToplevel, parameters, start, Location.Null)
+               {
+                       Container = container;
+               }
+               
+               public ToplevelBlock (Parameters parameters, Location start) :
+                       base (null, Flags.IsToplevel, parameters, start, Location.Null)
+               {
+               }
+
+               public ToplevelBlock (Flags flags, Parameters parameters, Location start) :
+                       base (null, flags | Flags.IsToplevel, parameters, start, Location.Null)
+               {
+               }
+
+               public ToplevelBlock (Location loc) : base (null, Flags.IsToplevel, loc, loc)
+               {
+               }
+
+               public void SetHaveAnonymousMethods (Location loc, AnonymousMethod host)
+               {
+                       if (capture_context == null)
+                               capture_context = new CaptureContext (this, loc, host);
+               }
+
+               public CaptureContext CaptureContext {
+                       get {
+                               return capture_context;
+                       }
+               }
+       }
+       
+       public class SwitchLabel {
+               Expression label;
+               object converted;
+               public Location loc;
+
+               Label il_label;
+               bool  il_label_set;
+               Label il_label_code;
+               bool  il_label_code_set;
+
+               //
+               // if expr == null, then it is the default case.
+               //
+               public SwitchLabel (Expression expr, Location l)
+               {
+                       label = expr;
+                       loc = l;
+               }
+
+               public Expression Label {
+                       get {
+                               return label;
+                       }
+               }
+
+               public object Converted {
+                       get {
+                               return converted;
+                       }
+               }
+
+               public Label GetILLabel (EmitContext ec)
+               {
+                       if (!il_label_set){
+                               il_label = ec.ig.DefineLabel ();
+                               il_label_set = true;
+                       }
+                       return il_label;
+               }
+
+               public Label GetILLabelCode (EmitContext ec)
+               {
+                       if (!il_label_code_set){
+                               il_label_code = ec.ig.DefineLabel ();
+                               il_label_code_set = true;
+                       }
+                       return il_label_code;
+               }                               
+               
+               //
+               // Resolves the expression, reduces it to a literal if possible
+               // and then converts it to the requested type.
+               //
+               public bool ResolveAndReduce (EmitContext ec, Type required_type)
+               {
+                       if (label == null)
+                               return true;
+                       
+                       Expression e = label.Resolve (ec);
+
+                       if (e == null)
+                               return false;
+
+                       if (!(e is Constant)){
+                               Report.Error (150, loc, "A constant value is expected, got: " + e);
+                               return false;
+                       }
+
+                       if (e is StringConstant || e is NullLiteral){
+                               if (required_type == TypeManager.string_type){
+                                       converted = e;
+                                       return true;
+                               }
+                       }
+
+                       converted = Expression.ConvertIntLiteral ((Constant) e, required_type, loc);
+                       if (converted == null)
+                               return false;
+
+                       return true;
+               }
+       }
+
+       public class SwitchSection {
+               // An array of SwitchLabels.
+               public readonly ArrayList Labels;
+               public readonly Block Block;
+               
+               public SwitchSection (ArrayList labels, Block block)
+               {
+                       Labels = labels;
+                       Block = block;
+               }
+       }
+       
+       public class Switch : Statement {
+               public readonly ArrayList Sections;
+               public Expression Expr;
+
+               /// <summary>
+               ///   Maps constants whose type type SwitchType to their  SwitchLabels.
+               /// </summary>
+               public Hashtable Elements;
+
+               /// <summary>
+               ///   The governing switch type
+               /// </summary>
+               public Type SwitchType;
+
+               //
+               // Computed
+               //
+               bool got_default;
+               Label default_target;
+               Expression new_expr;
+               bool is_constant;
+               SwitchSection constant_section;
+
+               //
+               // The types allowed to be implicitly cast from
+               // on the governing type
+               //
+               static Type [] allowed_types;
+               
+               public Switch (Expression e, ArrayList sects, Location l)
+               {
+                       Expr = e;
+                       Sections = sects;
+                       loc = l;
+               }
+
+               public bool GotDefault {
+                       get {
+                               return got_default;
+                       }
+               }
+
+               public Label DefaultTarget {
+                       get {
+                               return default_target;
+                       }
+               }
+
+               //
+               // Determines the governing type for a switch.  The returned
+               // expression might be the expression from the switch, or an
+               // expression that includes any potential conversions to the
+               // integral types or to string.
+               //
+               Expression SwitchGoverningType (EmitContext ec, Type t)
+               {
+                       if (t == TypeManager.int32_type ||
+                           t == TypeManager.uint32_type ||
+                           t == TypeManager.char_type ||
+                           t == TypeManager.byte_type ||
+                           t == TypeManager.sbyte_type ||
+                           t == TypeManager.ushort_type ||
+                           t == TypeManager.short_type ||
+                           t == TypeManager.uint64_type ||
+                           t == TypeManager.int64_type ||
+                           t == TypeManager.string_type ||
+                               t == TypeManager.bool_type ||
+                               t.IsSubclassOf (TypeManager.enum_type))
+                               return Expr;
+
+                       if (allowed_types == null){
+                               allowed_types = new Type [] {
+                                       TypeManager.int32_type,
+                                       TypeManager.uint32_type,
+                                       TypeManager.sbyte_type,
+                                       TypeManager.byte_type,
+                                       TypeManager.short_type,
+                                       TypeManager.ushort_type,
+                                       TypeManager.int64_type,
+                                       TypeManager.uint64_type,
+                                       TypeManager.char_type,
+                                       TypeManager.bool_type,
+                                       TypeManager.string_type
+                               };
+                       }
+
+                       //
+                       // Try to find a *user* defined implicit conversion.
+                       //
+                       // If there is no implicit conversion, or if there are multiple
+                       // conversions, we have to report an error
+                       //
+                       Expression converted = null;
+                       foreach (Type tt in allowed_types){
+                               Expression e;
+                               
+                               e = Convert.ImplicitUserConversion (ec, Expr, tt, loc);
+                               if (e == null)
+                                       continue;
+
+                               //
+                               // Ignore over-worked ImplicitUserConversions that do
+                               // an implicit conversion in addition to the user conversion.
+                               // 
+                               if (e is UserCast){
+                                       UserCast ue = e as UserCast;
+
+                                       if (ue.Source != Expr)
+                                               e = null;
+                               }
+                               
+                               if (converted != null){
+                                       Report.ExtraInformation (
+                                               loc,
+                                               String.Format ("reason: more than one conversion to an integral type exist for type {0}",
+                                                              TypeManager.CSharpName (Expr.Type)));
+                                       return null;
+                               } else {
+                                       converted = e;
+                               }
+                       }
+                       return converted;
+               }
+
+               static string Error152 {
+                       get {
+                               return "The label '{0}:' already occurs in this switch statement";
+                       }
+               }
+               
+               //
+               // Performs the basic sanity checks on the switch statement
+               // (looks for duplicate keys and non-constant expressions).
+               //
+               // It also returns a hashtable with the keys that we will later
+               // use to compute the switch tables
+               //
+               bool CheckSwitch (EmitContext ec)
+               {
+                       Type compare_type;
+                       bool error = false;
+                       Elements = new Hashtable ();
+                               
+                       got_default = false;
+
+                       if (TypeManager.IsEnumType (SwitchType)){
+                               compare_type = TypeManager.EnumToUnderlying (SwitchType);
+                       } else
+                               compare_type = SwitchType;
+                       
+                       foreach (SwitchSection ss in Sections){
+                               foreach (SwitchLabel sl in ss.Labels){
+                                       if (!sl.ResolveAndReduce (ec, SwitchType)){
+                                               error = true;
+                                               continue;
+                                       }
+
+                                       if (sl.Label == null){
+                                               if (got_default){
+                                                       Report.Error (152, sl.loc, Error152, "default");
+                                                       error = true;
+                                               }
+                                               got_default = true;
+                                               continue;
+                                       }
+                                       
+                                       object key = sl.Converted;
+
+                                       if (key is Constant)
+                                               key = ((Constant) key).GetValue ();
+
+                                       if (key == null)
+                                               key = NullLiteral.Null;
+                                       
+                                       string lname = null;
+                                       if (compare_type == TypeManager.uint64_type){
+                                               ulong v = (ulong) key;
+
+                                               if (Elements.Contains (v))
+                                                       lname = v.ToString ();
+                                               else
+                                                       Elements.Add (v, sl);
+                                       } else if (compare_type == TypeManager.int64_type){
+                                               long v = (long) key;
+
+                                               if (Elements.Contains (v))
+                                                       lname = v.ToString ();
+                                               else
+                                                       Elements.Add (v, sl);
+                                       } else if (compare_type == TypeManager.uint32_type){
+                                               uint v = (uint) key;
+
+                                               if (Elements.Contains (v))
+                                                       lname = v.ToString ();
+                                               else
+                                                       Elements.Add (v, sl);
+                                       } else if (compare_type == TypeManager.char_type){
+                                               char v = (char) key;
+                                               
+                                               if (Elements.Contains (v))
+                                                       lname = v.ToString ();
+                                               else
+                                                       Elements.Add (v, sl);
+                                       } else if (compare_type == TypeManager.byte_type){
+                                               byte v = (byte) key;
+                                               
+                                               if (Elements.Contains (v))
+                                                       lname = v.ToString ();
+                                               else
+                                                       Elements.Add (v, sl);
+                                       } else if (compare_type == TypeManager.sbyte_type){
+                                               sbyte v = (sbyte) key;
+                                               
+                                               if (Elements.Contains (v))
+                                                       lname = v.ToString ();
+                                               else
+                                                       Elements.Add (v, sl);
+                                       } else if (compare_type == TypeManager.short_type){
+                                               short v = (short) key;
+                                               
+                                               if (Elements.Contains (v))
+                                                       lname = v.ToString ();
+                                               else
+                                                       Elements.Add (v, sl);
+                                       } else if (compare_type == TypeManager.ushort_type){
+                                               ushort v = (ushort) key;
+                                               
+                                               if (Elements.Contains (v))
+                                                       lname = v.ToString ();
+                                               else
+                                                       Elements.Add (v, sl);
+                                       } else if (compare_type == TypeManager.string_type){
+                                               if (key is NullLiteral){
+                                                       if (Elements.Contains (NullLiteral.Null))
+                                                               lname = "null";
+                                                       else
+                                                               Elements.Add (NullLiteral.Null, null);
+                                               } else {
+                                                       string s = (string) key;
+
+                                                       if (Elements.Contains (s))
+                                                               lname = s;
+                                                       else
+                                                               Elements.Add (s, sl);
+                                               }
+                                       } else if (compare_type == TypeManager.int32_type) {
+                                               int v = (int) key;
+
+                                               if (Elements.Contains (v))
+                                                       lname = v.ToString ();
+                                               else
+                                                       Elements.Add (v, sl);
+                                       } else if (compare_type == TypeManager.bool_type) {
+                                               bool v = (bool) key;
+
+                                               if (Elements.Contains (v))
+                                                       lname = v.ToString ();
+                                               else
+                                                       Elements.Add (v, sl);
+                                       }
+                                       else
+                                       {
+                                               throw new Exception ("Unknown switch type!" +
+                                                                    SwitchType + " " + compare_type);
+                                       }
+
+                                       if (lname != null){
+                                               Report.Error (152, sl.loc, Error152, "case " + lname);
+                                               error = true;
+                                       }
+                               }
+                       }
+                       if (error)
+                               return false;
+                       
+                       return true;
+               }
+
+               void EmitObjectInteger (ILGenerator ig, object k)
+               {
+                       if (k is int)
+                               IntConstant.EmitInt (ig, (int) k);
+                       else if (k is Constant) {
+                               EmitObjectInteger (ig, ((Constant) k).GetValue ());
+                       } 
+                       else if (k is uint)
+                               IntConstant.EmitInt (ig, unchecked ((int) (uint) k));
+                       else if (k is long)
+                       {
+                               if ((long) k >= int.MinValue && (long) k <= int.MaxValue)
+                               {
+                                       IntConstant.EmitInt (ig, (int) (long) k);
+                                       ig.Emit (OpCodes.Conv_I8);
+                               }
+                               else
+                                       LongConstant.EmitLong (ig, (long) k);
+                       }
+                       else if (k is ulong)
+                       {
+                               if ((ulong) k < (1L<<32))
+                               {
+                                       IntConstant.EmitInt (ig, (int) (long) k);
+                                       ig.Emit (OpCodes.Conv_U8);
+                               }
+                               else
+                               {
+                                       LongConstant.EmitLong (ig, unchecked ((long) (ulong) k));
+                               }
+                       }
+                       else if (k is char)
+                               IntConstant.EmitInt (ig, (int) ((char) k));
+                       else if (k is sbyte)
+                               IntConstant.EmitInt (ig, (int) ((sbyte) k));
+                       else if (k is byte)
+                               IntConstant.EmitInt (ig, (int) ((byte) k));
+                       else if (k is short)
+                               IntConstant.EmitInt (ig, (int) ((short) k));
+                       else if (k is ushort)
+                               IntConstant.EmitInt (ig, (int) ((ushort) k));
+                       else if (k is bool)
+                               IntConstant.EmitInt (ig, ((bool) k) ? 1 : 0);
+                       else
+                               throw new Exception ("Unhandled case");
+               }
+               
+               // structure used to hold blocks of keys while calculating table switch
+               class KeyBlock : IComparable
+               {
+                       public KeyBlock (long _nFirst)
+                       {
+                               nFirst = nLast = _nFirst;
+                       }
+                       public long nFirst;
+                       public long nLast;
+                       public ArrayList rgKeys = null;
+                       // how many items are in the bucket
+                       public int Size = 1;
+                       public int Length
+                       {
+                               get { return (int) (nLast - nFirst + 1); }
+                       }
+                       public static long TotalLength (KeyBlock kbFirst, KeyBlock kbLast)
+                       {
+                               return kbLast.nLast - kbFirst.nFirst + 1;
+                       }
+                       public int CompareTo (object obj)
+                       {
+                               KeyBlock kb = (KeyBlock) obj;
+                               int nLength = Length;
+                               int nLengthOther = kb.Length;
+                               if (nLengthOther == nLength)
+                                       return (int) (kb.nFirst - nFirst);
+                               return nLength - nLengthOther;
+                       }
+               }
+
+               /// <summary>
+               /// This method emits code for a lookup-based switch statement (non-string)
+               /// Basically it groups the cases into blocks that are at least half full,
+               /// and then spits out individual lookup opcodes for each block.
+               /// It emits the longest blocks first, and short blocks are just
+               /// handled with direct compares.
+               /// </summary>
+               /// <param name="ec"></param>
+               /// <param name="val"></param>
+               /// <returns></returns>
+               void TableSwitchEmit (EmitContext ec, LocalBuilder val)
+               {
+                       int cElements = Elements.Count;
+                       object [] rgKeys = new object [cElements];
+                       Elements.Keys.CopyTo (rgKeys, 0);
+                       Array.Sort (rgKeys);
+
+                       // initialize the block list with one element per key
+                       ArrayList rgKeyBlocks = new ArrayList ();
+                       foreach (object key in rgKeys)
+                               rgKeyBlocks.Add (new KeyBlock (System.Convert.ToInt64 (key)));
+
+                       KeyBlock kbCurr;
+                       // iteratively merge the blocks while they are at least half full
+                       // there's probably a really cool way to do this with a tree...
+                       while (rgKeyBlocks.Count > 1)
+                       {
+                               ArrayList rgKeyBlocksNew = new ArrayList ();
+                               kbCurr = (KeyBlock) rgKeyBlocks [0];
+                               for (int ikb = 1; ikb < rgKeyBlocks.Count; ikb++)
+                               {
+                                       KeyBlock kb = (KeyBlock) rgKeyBlocks [ikb];
+                                       if ((kbCurr.Size + kb.Size) * 2 >=  KeyBlock.TotalLength (kbCurr, kb))
+                                       {
+                                               // merge blocks
+                                               kbCurr.nLast = kb.nLast;
+                                               kbCurr.Size += kb.Size;
+                                       }
+                                       else
+                                       {
+                                               // start a new block
+                                               rgKeyBlocksNew.Add (kbCurr);
+                                               kbCurr = kb;
+                                       }
+                               }
+                               rgKeyBlocksNew.Add (kbCurr);
+                               if (rgKeyBlocks.Count == rgKeyBlocksNew.Count)
+                                       break;
+                               rgKeyBlocks = rgKeyBlocksNew;
+                       }
+
+                       // initialize the key lists
+                       foreach (KeyBlock kb in rgKeyBlocks)
+                               kb.rgKeys = new ArrayList ();
+
+                       // fill the key lists
+                       int iBlockCurr = 0;
+                       if (rgKeyBlocks.Count > 0) {
+                               kbCurr = (KeyBlock) rgKeyBlocks [0];
+                               foreach (object key in rgKeys)
+                               {
+                                       bool fNextBlock = (key is UInt64) ? (ulong) key > (ulong) kbCurr.nLast :
+                                               System.Convert.ToInt64 (key) > kbCurr.nLast;
+                                       if (fNextBlock)
+                                               kbCurr = (KeyBlock) rgKeyBlocks [++iBlockCurr];
+                                       kbCurr.rgKeys.Add (key);
+                               }
+                       }
+
+                       // sort the blocks so we can tackle the largest ones first
+                       rgKeyBlocks.Sort ();
+
+                       // okay now we can start...
+                       ILGenerator ig = ec.ig;
+                       Label lblEnd = ig.DefineLabel ();       // at the end ;-)
+                       Label lblDefault = ig.DefineLabel ();
+
+                       Type typeKeys = null;
+                       if (rgKeys.Length > 0)
+                               typeKeys = rgKeys [0].GetType ();       // used for conversions
+
+                       Type compare_type;
+                       
+                       if (TypeManager.IsEnumType (SwitchType))
+                               compare_type = TypeManager.EnumToUnderlying (SwitchType);
+                       else
+                               compare_type = SwitchType;
+                       
+                       for (int iBlock = rgKeyBlocks.Count - 1; iBlock >= 0; --iBlock)
+                       {
+                               KeyBlock kb = ((KeyBlock) rgKeyBlocks [iBlock]);
+                               lblDefault = (iBlock == 0) ? DefaultTarget : ig.DefineLabel ();
+                               if (kb.Length <= 2)
+                               {
+                                       foreach (object key in kb.rgKeys)
+                                       {
+                                               ig.Emit (OpCodes.Ldloc, val);
+                                               EmitObjectInteger (ig, key);
+                                               SwitchLabel sl = (SwitchLabel) Elements [key];
+                                               ig.Emit (OpCodes.Beq, sl.GetILLabel (ec));
+                                       }
+                               }
+                               else
+                               {
+                                       // TODO: if all the keys in the block are the same and there are
+                                       //       no gaps/defaults then just use a range-check.
+                                       if (compare_type == TypeManager.int64_type ||
+                                               compare_type == TypeManager.uint64_type)
+                                       {
+                                               // TODO: optimize constant/I4 cases
+
+                                               // check block range (could be > 2^31)
+                                               ig.Emit (OpCodes.Ldloc, val);
+                                               EmitObjectInteger (ig, System.Convert.ChangeType (kb.nFirst, typeKeys));
+                                               ig.Emit (OpCodes.Blt, lblDefault);
+                                               ig.Emit (OpCodes.Ldloc, val);
+                                               EmitObjectInteger (ig, System.Convert.ChangeType (kb.nLast, typeKeys));
+                                               ig.Emit (OpCodes.Bgt, lblDefault);
+
+                                               // normalize range
+                                               ig.Emit (OpCodes.Ldloc, val);
+                                               if (kb.nFirst != 0)
+                                               {
+                                                       EmitObjectInteger (ig, System.Convert.ChangeType (kb.nFirst, typeKeys));
+                                                       ig.Emit (OpCodes.Sub);
+                                               }
+                                               ig.Emit (OpCodes.Conv_I4);      // assumes < 2^31 labels!
+                                       }
+                                       else
+                                       {
+                                               // normalize range
+                                               ig.Emit (OpCodes.Ldloc, val);
+                                               int nFirst = (int) kb.nFirst;
+                                               if (nFirst > 0)
+                                               {
+                                                       IntConstant.EmitInt (ig, nFirst);
+                                                       ig.Emit (OpCodes.Sub);
+                                               }
+                                               else if (nFirst < 0)
+                                               {
+                                                       IntConstant.EmitInt (ig, -nFirst);
+                                                       ig.Emit (OpCodes.Add);
+                                               }
+                                       }
+
+                                       // first, build the list of labels for the switch
+                                       int iKey = 0;
+                                       int cJumps = kb.Length;
+                                       Label [] rgLabels = new Label [cJumps];
+                                       for (int iJump = 0; iJump < cJumps; iJump++)
+                                       {
+                                               object key = kb.rgKeys [iKey];
+                                               if (System.Convert.ToInt64 (key) == kb.nFirst + iJump)
+                                               {
+                                                       SwitchLabel sl = (SwitchLabel) Elements [key];
+                                                       rgLabels [iJump] = sl.GetILLabel (ec);
+                                                       iKey++;
+                                               }
+                                               else
+                                                       rgLabels [iJump] = lblDefault;
+                                       }
+                                       // emit the switch opcode
+                                       ig.Emit (OpCodes.Switch, rgLabels);
+                               }
+
+                               // mark the default for this block
+                               if (iBlock != 0)
+                                       ig.MarkLabel (lblDefault);
+                       }
+
+                       // TODO: find the default case and emit it here,
+                       //       to prevent having to do the following jump.
+                       //       make sure to mark other labels in the default section
+
+                       // the last default just goes to the end
+                       ig.Emit (OpCodes.Br, lblDefault);
+
+                       // now emit the code for the sections
+                       bool fFoundDefault = false;
+                       foreach (SwitchSection ss in Sections)
+                       {
+                               foreach (SwitchLabel sl in ss.Labels)
+                               {
+                                       ig.MarkLabel (sl.GetILLabel (ec));
+                                       ig.MarkLabel (sl.GetILLabelCode (ec));
+                                       if (sl.Label == null)
+                                       {
+                                               ig.MarkLabel (lblDefault);
+                                               fFoundDefault = true;
+                                       }
+                               }
+                               ss.Block.Emit (ec);
+                               //ig.Emit (OpCodes.Br, lblEnd);
+                       }
+                       
+                       if (!fFoundDefault) {
+                               ig.MarkLabel (lblDefault);
+                       }
+                       ig.MarkLabel (lblEnd);
+               }
+               //
+               // This simple emit switch works, but does not take advantage of the
+               // `switch' opcode. 
+               // TODO: remove non-string logic from here
+               // TODO: binary search strings?
+               //
+               void SimpleSwitchEmit (EmitContext ec, LocalBuilder val)
+               {
+                       ILGenerator ig = ec.ig;
+                       Label end_of_switch = ig.DefineLabel ();
+                       Label next_test = ig.DefineLabel ();
+                       Label null_target = ig.DefineLabel ();
+                       bool default_found = false;
+                       bool first_test = true;
+                       bool pending_goto_end = false;
+                       bool null_found;
+                       bool default_at_end = false;
+                       
+                       ig.Emit (OpCodes.Ldloc, val);
+                       
+                       if (Elements.Contains (NullLiteral.Null)){
+                               ig.Emit (OpCodes.Brfalse, null_target);
+                       } else
+                               ig.Emit (OpCodes.Brfalse, default_target);
+                       
+                       ig.Emit (OpCodes.Ldloc, val);
+                       ig.Emit (OpCodes.Call, TypeManager.string_isinterneted_string);
+                       ig.Emit (OpCodes.Stloc, val);
+               
+                       int section_count = Sections.Count;
+                       for (int section = 0; section < section_count; section++){
+                               SwitchSection ss = (SwitchSection) Sections [section];
+                               Label sec_begin = ig.DefineLabel ();
+
+                               if (pending_goto_end)
+                                       ig.Emit (OpCodes.Br, end_of_switch);
+
+                               int label_count = ss.Labels.Count;
+                               bool mark_default = false;
+                               null_found = false;
+                               for (int label = 0; label < label_count; label++){
+                                       SwitchLabel sl = (SwitchLabel) ss.Labels [label];
+                                       ig.MarkLabel (sl.GetILLabel (ec));
+                                       
+                                       if (!first_test){
+                                               ig.MarkLabel (next_test);
+                                               next_test = ig.DefineLabel ();
+                                       }
+                                       //
+                                       // If we are the default target
+                                       //
+                                       if (sl.Label == null){
+                                               if (label+1 == label_count)
+                                                       default_at_end = true;
+                                               mark_default = true;
+                                               default_found = true;
+                                       } else {
+                                               object lit = sl.Converted;
+
+                                               if (lit is NullLiteral){
+                                                       null_found = true;
+                                                       if (label_count == 1)
+                                                               ig.Emit (OpCodes.Br, next_test);
+                                                       continue;
+                                                                             
+                                               }
+                                               StringConstant str = (StringConstant) lit;
+                                               
+                                               ig.Emit (OpCodes.Ldloc, val);
+                                               ig.Emit (OpCodes.Ldstr, str.Value);
+                                               if (label_count == 1)
+                                                       ig.Emit (OpCodes.Bne_Un, next_test);
+                                               else {
+                                                       if (label+1 == label_count)
+                                                               ig.Emit (OpCodes.Bne_Un, next_test);
+                                                       else
+                                                               ig.Emit (OpCodes.Beq, sec_begin);
+                                               }
+                                       }
+                               }
+                               if (null_found)
+                                       ig.MarkLabel (null_target);
+                               ig.MarkLabel (sec_begin);
+                               foreach (SwitchLabel sl in ss.Labels)
+                                       ig.MarkLabel (sl.GetILLabelCode (ec));
+
+                               if (mark_default)
+                                       ig.MarkLabel (default_target);
+                               ss.Block.Emit (ec);
+                               pending_goto_end = !ss.Block.HasRet;
+                               first_test = false;
+                       }
+                       ig.MarkLabel (next_test);
+                       if (default_found){
+                               if (!default_at_end)
+                                       ig.Emit (OpCodes.Br, default_target);
+                       } else 
+                               ig.MarkLabel (default_target);
+                       ig.MarkLabel (end_of_switch);
+               }
+
+               SwitchSection FindSection (SwitchLabel label)
+               {
+                       foreach (SwitchSection ss in Sections){
+                               foreach (SwitchLabel sl in ss.Labels){
+                                       if (label == sl)
+                                               return ss;
+                               }
+                       }
+
+                       return null;
+               }
+
+               bool ResolveConstantSwitch (EmitContext ec)
+               {
+                       object key = ((Constant) new_expr).GetValue ();
+                       SwitchLabel label = (SwitchLabel) Elements [key];
+
+                       if (label == null)
+                               return true;
+
+                       constant_section = FindSection (label);
+                       if (constant_section == null)
+                               return true;
+
+                       if (constant_section.Block.Resolve (ec) != true)
+                               return false;
+
+                       return true;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       Expr = Expr.Resolve (ec);
+                       if (Expr == null)
+                               return false;
+
+                       new_expr = SwitchGoverningType (ec, Expr.Type);
+                       if (new_expr == null){
+                               Report.Error (151, loc, "An integer type or string was expected for switch");
+                               return false;
+                       }
+
+                       // Validate switch.
+                       SwitchType = new_expr.Type;
+
+                       if (!CheckSwitch (ec))
+                               return false;
+
+                       Switch old_switch = ec.Switch;
+                       ec.Switch = this;
+                       ec.Switch.SwitchType = SwitchType;
+
+                       Report.Debug (1, "START OF SWITCH BLOCK", loc, ec.CurrentBranching);
+                       ec.StartFlowBranching (FlowBranching.BranchingType.Switch, loc);
+
+                       is_constant = new_expr is Constant;
+                       if (is_constant) {
+                               object key = ((Constant) new_expr).GetValue ();
+                               SwitchLabel label = (SwitchLabel) Elements [key];
+
+                               constant_section = FindSection (label);
+                       }
+
+                       bool first = true;
+                       foreach (SwitchSection ss in Sections){
+                               if (!first)
+                                       ec.CurrentBranching.CreateSibling (
+                                               null, FlowBranching.SiblingType.SwitchSection);
+                               else
+                                       first = false;
+
+                               if (is_constant && (ss != constant_section)) {
+                                       // If we're a constant switch, we're only emitting
+                                       // one single section - mark all the others as
+                                       // unreachable.
+                                       ec.CurrentBranching.CurrentUsageVector.Goto ();
+                                       if (!ss.Block.ResolveUnreachable (ec, true))
+                                               return false;
+                               } else {
+                                       if (!ss.Block.Resolve (ec))
+                                       return false;
+                       }
+                       }
+
+                       if (!got_default)
+                               ec.CurrentBranching.CreateSibling (
+                                       null, FlowBranching.SiblingType.SwitchSection);
+
+                       FlowBranching.Reachability reachability = ec.EndFlowBranching ();
+                       ec.Switch = old_switch;
+
+                       Report.Debug (1, "END OF SWITCH BLOCK", loc, ec.CurrentBranching,
+                                     reachability);
+
+                       return true;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       // Store variable for comparission purposes
+                       LocalBuilder value;
+                       if (!is_constant) {
+                               value = ig.DeclareLocal (SwitchType);
+                       new_expr.Emit (ec);
+                               ig.Emit (OpCodes.Stloc, value);
+                       } else
+                               value = null;
+
+                       default_target = ig.DefineLabel ();
+
+                       //
+                       // Setup the codegen context
+                       //
+                       Label old_end = ec.LoopEnd;
+                       Switch old_switch = ec.Switch;
+                       
+                       ec.LoopEnd = ig.DefineLabel ();
+                       ec.Switch = this;
+
+                       // Emit Code.
+                       if (is_constant) {
+                               if (constant_section != null)
+                                       constant_section.Block.Emit (ec);
+                       } else if (SwitchType == TypeManager.string_type)
+                               SimpleSwitchEmit (ec, value);
+                       else
+                               TableSwitchEmit (ec, value);
+
+                       // Restore context state. 
+                       ig.MarkLabel (ec.LoopEnd);
+
+                       //
+                       // Restore the previous context
+                       //
+                       ec.LoopEnd = old_end;
+                       ec.Switch = old_switch;
+               }
+       }
+
+       public abstract class ExceptionStatement : Statement
+       {
+               public abstract void EmitFinally (EmitContext ec);
+
+               protected bool emit_finally = true;
+               ArrayList parent_vectors;
+
+               protected void DoEmitFinally (EmitContext ec)
+               {
+                       if (emit_finally)
+                               ec.ig.BeginFinallyBlock ();
+                       else
+                               ec.CurrentIterator.MarkFinally (ec, parent_vectors);
+                       EmitFinally (ec);
+               }
+
+               protected void ResolveFinally (FlowBranchingException branching)
+               {
+                       emit_finally = branching.EmitFinally;
+                       if (!emit_finally)
+                               branching.Parent.StealFinallyClauses (ref parent_vectors);
+               }
+       }
+
+       public class Lock : ExceptionStatement {
+               Expression expr;
+               Statement Statement;
+               LocalBuilder temp;
+                       
+               public Lock (Expression expr, Statement stmt, Location l)
+               {
+                       this.expr = expr;
+                       Statement = stmt;
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       expr = expr.Resolve (ec);
+                       if (expr == null)
+                               return false;
+
+                       if (expr.Type.IsValueType){
+                               Error (185, "lock statement requires the expression to be " +
+                                      " a reference type (type is: `{0}'",
+                                      TypeManager.CSharpName (expr.Type));
+                               return false;
+                       }
+
+                       FlowBranchingException branching = ec.StartFlowBranching (this);
+                       bool ok = Statement.Resolve (ec);
+                       if (!ok) {
+                               ec.KillFlowBranching ();
+                               return false;
+                       }
+
+                       ResolveFinally (branching);
+
+                       FlowBranching.Reachability reachability = ec.EndFlowBranching ();
+                       if (reachability.Returns != FlowBranching.FlowReturns.Always) {
+                               // Unfortunately, System.Reflection.Emit automatically emits
+                               // a leave 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.
+                               ec.NeedReturnLabel ();
+                       }
+
+                       return true;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       Type type = expr.Type;
+                       
+                       ILGenerator ig = ec.ig;
+                       temp = ig.DeclareLocal (type);
+                               
+                       expr.Emit (ec);
+                       ig.Emit (OpCodes.Dup);
+                       ig.Emit (OpCodes.Stloc, temp);
+                       ig.Emit (OpCodes.Call, TypeManager.void_monitor_enter_object);
+
+                       // try
+                       if (emit_finally)
+                               ig.BeginExceptionBlock ();
+                       Statement.Emit (ec);
+                       
+                       // finally
+                       DoEmitFinally (ec);
+                       if (emit_finally)
+                               ig.EndExceptionBlock ();
+               }
+
+               public override void EmitFinally (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       ig.Emit (OpCodes.Ldloc, temp);
+                       ig.Emit (OpCodes.Call, TypeManager.void_monitor_exit_object);
+               }
+       }
+
+       public class Unchecked : Statement {
+               public readonly Block Block;
+               
+               public Unchecked (Block b)
+               {
+                       Block = b;
+                       b.Unchecked = true;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       bool previous_state = ec.CheckState;
+                       bool previous_state_const = ec.ConstantCheckState;
+
+                       ec.CheckState = false;
+                       ec.ConstantCheckState = false;
+                       bool ret = Block.Resolve (ec);
+                       ec.CheckState = previous_state;
+                       ec.ConstantCheckState = previous_state_const;
+
+                       return ret;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       bool previous_state = ec.CheckState;
+                       bool previous_state_const = ec.ConstantCheckState;
+                       
+                       ec.CheckState = false;
+                       ec.ConstantCheckState = false;
+                       Block.Emit (ec);
+                       ec.CheckState = previous_state;
+                       ec.ConstantCheckState = previous_state_const;
+               }
+       }
+
+       public class Checked : Statement {
+               public readonly Block Block;
+               
+               public Checked (Block b)
+               {
+                       Block = b;
+                       b.Unchecked = false;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       bool previous_state = ec.CheckState;
+                       bool previous_state_const = ec.ConstantCheckState;
+                       
+                       ec.CheckState = true;
+                       ec.ConstantCheckState = true;
+                       bool ret = Block.Resolve (ec);
+                       ec.CheckState = previous_state;
+                       ec.ConstantCheckState = previous_state_const;
+
+                       return ret;
+               }
+
+               protected override void DoEmit (EmitContext ec)
+               {
+                       bool previous_state = ec.CheckState;
+                       bool previous_state_const = ec.ConstantCheckState;
+                       
+                       ec.CheckState = true;
+                       ec.ConstantCheckState = true;
+                       Block.Emit (ec);
+                       ec.CheckState = previous_state;
+                       ec.ConstantCheckState = previous_state_const;
+               }
+       }
+
+       public class Unsafe : Statement {
+               public readonly Block Block;
+
+               public Unsafe (Block b)
+               {
+                       Block = b;
+                       Block.Unsafe = true;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       bool previous_state = ec.InUnsafe;
+                       bool val;
+                       
+                       ec.InUnsafe = true;
+                       val = Block.Resolve (ec);
+                       ec.InUnsafe = previous_state;
+
+                       return val;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       bool previous_state = ec.InUnsafe;
+                       
+                       ec.InUnsafe = true;
+                       Block.Emit (ec);
+                       ec.InUnsafe = previous_state;
+               }
+       }
+
+       // 
+       // Fixed statement
+       //
+       public class Fixed : Statement {
+               Expression type;
+               ArrayList declarators;
+               Statement statement;
+               Type expr_type;
+               FixedData[] data;
+               bool has_ret;
+
+               struct FixedData {
+                       public bool is_object;
+                       public LocalInfo vi;
+                       public Expression expr;
+                       public Expression converted;
+               }                       
+
+               public Fixed (Expression type, ArrayList decls, Statement stmt, Location l)
+               {
+                       this.type = type;
+                       declarators = decls;
+                       statement = stmt;
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       if (!ec.InUnsafe){
+                               Expression.UnsafeError (loc);
+                               return false;
+                       }
+                       
+                       TypeExpr texpr = type.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return false;
+
+                       expr_type = texpr.Type;
+
+                       CheckObsolete (expr_type);
+
+                       if (ec.RemapToProxy){
+                               Report.Error (-210, loc, "Fixed statement not allowed in iterators");
+                               return false;
+                       }
+                       
+                       data = new FixedData [declarators.Count];
+
+                       if (!expr_type.IsPointer){
+                               Report.Error (209, loc, "Variables in a fixed statement must be pointers");
+                               return false;
+                       }
+                       
+                       int i = 0;
+                       foreach (Pair p in declarators){
+                               LocalInfo vi = (LocalInfo) p.First;
+                               Expression e = (Expression) p.Second;
+
+                               vi.VariableInfo.SetAssigned (ec);
+                               vi.ReadOnly = true;
+
+                               //
+                               // The rules for the possible declarators are pretty wise,
+                               // but the production on the grammar is more concise.
+                               //
+                               // So we have to enforce these rules here.
+                               //
+                               // We do not resolve before doing the case 1 test,
+                               // because the grammar is explicit in that the token &
+                               // is present, so we need to test for this particular case.
+                               //
+
+                               if (e is Cast){
+                                       Report.Error (254, loc, "Cast expression not allowed as right hand expression in fixed statement");
+                                       return false;
+                               }
+                               
+                               //
+                               // Case 1: & object.
+                               //
+                               if (e is Unary && ((Unary) e).Oper == Unary.Operator.AddressOf){
+                                       Expression child = ((Unary) e).Expr;
+
+                                       if (child is ParameterReference || child is LocalVariableReference){
+                                               Report.Error (
+                                                       213, loc, 
+                                                       "No need to use fixed statement for parameters or " +
+                                                       "local variable declarations (address is already " +
+                                                       "fixed)");
+                                               return false;
+                                       }
+
+                                       ec.InFixedInitializer = true;
+                                       e = e.Resolve (ec);
+                                       ec.InFixedInitializer = false;
+                                       if (e == null)
+                                               return false;
+
+                                       child = ((Unary) e).Expr;
+                                       
+                                       if (!TypeManager.VerifyUnManaged (child.Type, loc))
+                                               return false;
+
+                                       data [i].is_object = true;
+                                       data [i].expr = e;
+                                       data [i].converted = null;
+                                       data [i].vi = vi;
+                                       i++;
+
+                                       continue;
+                               }
+
+                               ec.InFixedInitializer = true;
+                               e = e.Resolve (ec);
+                               ec.InFixedInitializer = false;
+                               if (e == null)
+                                       return false;
+
+                               //
+                               // Case 2: Array
+                               //
+                               if (e.Type.IsArray){
+                                       Type array_type = TypeManager.GetElementType (e.Type);
+                                       
+                                       //
+                                       // Provided that array_type is unmanaged,
+                                       //
+                                       if (!TypeManager.VerifyUnManaged (array_type, loc))
+                                               return false;
+
+                                       //
+                                       // and T* is implicitly convertible to the
+                                       // pointer type given in the fixed statement.
+                                       //
+                                       ArrayPtr array_ptr = new ArrayPtr (e, loc);
+                                       
+                                       Expression converted = Convert.ImplicitConversionRequired (
+                                               ec, array_ptr, vi.VariableType, loc);
+                                       if (converted == null)
+                                               return false;
+
+                                       data [i].is_object = false;
+                                       data [i].expr = e;
+                                       data [i].converted = converted;
+                                       data [i].vi = vi;
+                                       i++;
+
+                                       continue;
+                               }
+
+                               //
+                               // Case 3: string
+                               //
+                               if (e.Type == TypeManager.string_type){
+                                       data [i].is_object = false;
+                                       data [i].expr = e;
+                                       data [i].converted = null;
+                                       data [i].vi = vi;
+                                       i++;
+                                       continue;
+                               }
+
+                               //
+                               // For other cases, flag a `this is already fixed expression'
+                               //
+                               if (e is LocalVariableReference || e is ParameterReference ||
+                                   Convert.ImplicitConversionExists (ec, e, vi.VariableType)){
+                                   
+                                       Report.Error (245, loc, "right hand expression is already fixed, no need to use fixed statement ");
+                                       return false;
+                               }
+
+                               Report.Error (245, loc, "Fixed statement only allowed on strings, arrays or address-of expressions");
+                               return false;
+                       }
+
+                       ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc);
+
+                       if (!statement.Resolve (ec)) {
+                               ec.KillFlowBranching ();
+                               return false;
+                       }
+
+                       FlowBranching.Reachability reachability = ec.EndFlowBranching ();
+                       has_ret = reachability.IsUnreachable;
+
+                       return true;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       LocalBuilder [] clear_list = new LocalBuilder [data.Length];
+                       
+                       for (int i = 0; i < data.Length; i++) {
+                               LocalInfo vi = data [i].vi;
+
+                               //
+                               // Case 1: & object.
+                               //
+                               if (data [i].is_object) {
+                                       //
+                                       // Store pointer in pinned location
+                                       //
+                                       data [i].expr.Emit (ec);
+                                       ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+                                       clear_list [i] = vi.LocalBuilder;
+                                       continue;
+                               }
+
+                               //
+                               // Case 2: Array
+                               //
+                               if (data [i].expr.Type.IsArray){
+                                       //
+                                       // Store pointer in pinned location
+                                       //
+                                       data [i].converted.Emit (ec);
+                                       
+                                       ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+                                       clear_list [i] = vi.LocalBuilder;
+                                       continue;
+                               }
+
+                               //
+                               // Case 3: string
+                               //
+                               if (data [i].expr.Type == TypeManager.string_type){
+                                       LocalBuilder pinned_string = TypeManager.DeclareLocalPinned (ig, TypeManager.string_type);
+                                       clear_list [i] = pinned_string;
+                                       
+                                       data [i].expr.Emit (ec);
+                                       ig.Emit (OpCodes.Stloc, pinned_string);
+
+                                       Expression sptr = new StringPtr (pinned_string, loc);
+                                       Expression converted = Convert.ImplicitConversionRequired (
+                                               ec, sptr, vi.VariableType, loc);
+                                       
+                                       if (converted == null)
+                                               continue;
+
+                                       converted.Emit (ec);
+                                       ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+                               }
+                       }
+
+                       statement.Emit (ec);
+
+                       if (has_ret)
+                               return;
+
+                       //
+                       // Clear the pinned variable
+                       //
+                       for (int i = 0; i < data.Length; i++) {
+                               if (data [i].is_object || data [i].expr.Type.IsArray) {
+                                       ig.Emit (OpCodes.Ldc_I4_0);
+                                       ig.Emit (OpCodes.Conv_U);
+                                       ig.Emit (OpCodes.Stloc, clear_list [i]);
+                               } else if (data [i].expr.Type == TypeManager.string_type){
+                                       ig.Emit (OpCodes.Ldnull);
+                                       ig.Emit (OpCodes.Stloc, clear_list [i]);
+                               }
+                       }
+               }
+       }
+       
+       public class Catch: Statement {
+               public readonly string Name;
+               public readonly Block  Block;
+
+               Expression type_expr;
+               Type type;
+               
+               public Catch (Expression type, string name, Block block, Location l)
+               {
+                       type_expr = type;
+                       Name = name;
+                       Block = block;
+                       loc = l;
+               }
+
+               public Type CatchType {
+                       get {
+                               return type;
+                       }
+               }
+
+               public bool IsGeneral {
+                       get {
+                               return type_expr == null;
+                       }
+               }
+
+               protected override void DoEmit(EmitContext ec)
+               {
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       if (type_expr != null) {
+                               TypeExpr te = type_expr.ResolveAsTypeTerminal (ec);
+                               if (te == null)
+                                       return false;
+
+                               type = te.Type;
+
+                               CheckObsolete (type);
+
+                               if (type != TypeManager.exception_type && !type.IsSubclassOf (TypeManager.exception_type)){
+                                       Error (155, "The type caught or thrown must be derived from System.Exception");
+                                       return false;
+                               }
+                       } else
+                               type = null;
+
+                       return Block.Resolve (ec);
+               }
+       }
+
+       public class Try : ExceptionStatement {
+               public readonly Block Fini, Block;
+               public readonly ArrayList Specific;
+               public readonly Catch General;
+
+               bool need_exc_block;
+               
+               //
+               // specific, general and fini might all be null.
+               //
+               public Try (Block block, ArrayList specific, Catch general, Block fini, Location l)
+               {
+                       if (specific == null && general == null){
+                               Console.WriteLine ("CIR.Try: Either specific or general have to be non-null");
+                       }
+                       
+                       this.Block = block;
+                       this.Specific = specific;
+                       this.General = general;
+                       this.Fini = fini;
+                       loc = l;
+               }
+
+               public override bool Resolve (EmitContext ec)
+               {
+                       bool ok = true;
+                       
+                       FlowBranchingException branching = ec.StartFlowBranching (this);
+
+                       Report.Debug (1, "START OF TRY BLOCK", Block.StartLocation);
+
+                       if (!Block.Resolve (ec))
+                               ok = false;
+
+                       FlowBranching.UsageVector vector = ec.CurrentBranching.CurrentUsageVector;
+
+                       Report.Debug (1, "START OF CATCH BLOCKS", vector);
+
+                       Type[] prevCatches = new Type [Specific.Count];
+                       int last_index = 0;
+                       foreach (Catch c in Specific){
+                               ec.CurrentBranching.CreateSibling (
+                                       c.Block, FlowBranching.SiblingType.Catch);
+
+                               Report.Debug (1, "STARTED SIBLING FOR CATCH", ec.CurrentBranching);
+
+                               if (c.Name != null) {
+                                       LocalInfo vi = c.Block.GetLocalInfo (c.Name);
+                                       if (vi == null)
+                                               throw new Exception ();
+
+                                       vi.VariableInfo = null;
+                               }
+
+                               if (!c.Resolve (ec))
+                                       return false;
+
+                               Type resolvedType = c.CatchType;
+                               for (int ii = 0; ii < last_index; ++ii) {
+                                       if (resolvedType == prevCatches [ii] || resolvedType.IsSubclassOf (prevCatches [ii])) {
+                                               Report.Error (160, c.loc, "A previous catch clause already catches all exceptions of this or a super type '{0}'", prevCatches [ii].FullName);
+                                               return false;
+                                       }
+                               }
+
+                               prevCatches [last_index++] = resolvedType;
+                               need_exc_block = true;
+                       }
+
+                       Report.Debug (1, "END OF CATCH BLOCKS", ec.CurrentBranching);
+
+                       if (General != null){
+                               ec.CurrentBranching.CreateSibling (
+                                       General.Block, FlowBranching.SiblingType.Catch);
+
+                               Report.Debug (1, "STARTED SIBLING FOR GENERAL", ec.CurrentBranching);
+
+                               if (!General.Resolve (ec))
+                                       ok = false;
+
+                               need_exc_block = true;
+                       }
+
+                       Report.Debug (1, "END OF GENERAL CATCH BLOCKS", ec.CurrentBranching);
+
+                       if (Fini != null) {
+                               if (ok)
+                                       ec.CurrentBranching.CreateSibling (
+                                               Fini, FlowBranching.SiblingType.Finally);
+
+                               Report.Debug (1, "STARTED SIBLING FOR FINALLY", ec.CurrentBranching, vector);
+
+                               if (!Fini.Resolve (ec))
+                                       ok = false;
+                       }
+
+                       ResolveFinally (branching);
+                       need_exc_block |= emit_finally;
+
+                       FlowBranching.Reachability reachability = ec.EndFlowBranching ();
+
+                       FlowBranching.UsageVector f_vector = ec.CurrentBranching.CurrentUsageVector;
+
+                       Report.Debug (1, "END OF TRY", ec.CurrentBranching, reachability, vector, f_vector);
+
+                       if (reachability.Returns != FlowBranching.FlowReturns.Always) {
+                               // Unfortunately, System.Reflection.Emit automatically emits
+                               // a leave 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.
+                               ec.NeedReturnLabel ();
+                       }
+
+                       return ok;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       if (need_exc_block)
+                               ig.BeginExceptionBlock ();
+                       Block.Emit (ec);
+
+                       foreach (Catch c in Specific){
+                               LocalInfo vi;
+                               
+                               ig.BeginCatchBlock (c.CatchType);
+
+                               if (c.Name != null){
+                                       vi = c.Block.GetLocalInfo (c.Name);
+                                       if (vi == null)
+                                               throw new Exception ("Variable does not exist in this block");
+
+                                       ig.Emit (OpCodes.Stloc, vi.LocalBuilder);
+                               } else
+                                       ig.Emit (OpCodes.Pop);
+                               
+                               c.Block.Emit (ec);
+                       }
+
+                       if (General != null){
+                               ig.BeginCatchBlock (TypeManager.object_type);
+                               ig.Emit (OpCodes.Pop);
+                               General.Block.Emit (ec);
+                       }
+
+                       DoEmitFinally (ec);
+                       if (need_exc_block)
+                               ig.EndExceptionBlock ();
+               }
+
+               public override void EmitFinally (EmitContext ec)
+               {
+                       if (Fini != null){
+                               Fini.Emit (ec);
+                       }
+               }
+       }
+
+       public class Using : ExceptionStatement {
+               object expression_or_block;
+               Statement Statement;
+               ArrayList var_list;
+               Expression expr;
+               Type expr_type;
+               Expression conv;
+               Expression [] resolved_vars;
+               Expression [] converted_vars;
+               ExpressionStatement [] assign;
+               LocalBuilder local_copy;
+               
+               public Using (object expression_or_block, Statement stmt, Location l)
+               {
+                       this.expression_or_block = expression_or_block;
+                       Statement = stmt;
+                       loc = l;
+               }
+
+               //
+               // Resolves for the case of using using a local variable declaration.
+               //
+               bool ResolveLocalVariableDecls (EmitContext ec)
+               {
+                       int i = 0;
+
+                       TypeExpr texpr = expr.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return false;
+
+                       expr_type = texpr.Type;
+
+                       //
+                       // The type must be an IDisposable or an implicit conversion
+                       // must exist.
+                       //
+                       converted_vars = new Expression [var_list.Count];
+                       resolved_vars = new Expression [var_list.Count];
+                       assign = new ExpressionStatement [var_list.Count];
+
+                       bool need_conv = !TypeManager.ImplementsInterface (
+                               expr_type, TypeManager.idisposable_type);
+
+                       foreach (DictionaryEntry e in var_list){
+                               Expression var = (Expression) e.Key;
+
+                               var = var.ResolveLValue (ec, new EmptyExpression ());
+                               if (var == null)
+                                       return false;
+
+                               resolved_vars [i] = var;
+
+                               if (!need_conv) {
+                                       i++;
+                                       continue;
+                               }
+
+                               converted_vars [i] = Convert.ImplicitConversionRequired (
+                                       ec, var, TypeManager.idisposable_type, loc);
+
+                               if (converted_vars [i] == null)
+                                       return false;
+
+                               i++;
+                       }
+
+                       i = 0;
+                       foreach (DictionaryEntry e in var_list){
+                               Expression var = resolved_vars [i];
+                               Expression new_expr = (Expression) e.Value;
+                               Expression a;
+
+                               a = new Assign (var, new_expr, loc);
+                               a = a.Resolve (ec);
+                               if (a == null)
+                                       return false;
+
+                               if (!need_conv)
+                                       converted_vars [i] = var;
+                               assign [i] = (ExpressionStatement) a;
+                               i++;
+                       }
+
+                       return true;
+               }
+
+               bool ResolveExpression (EmitContext ec)
+               {
+                       if (!TypeManager.ImplementsInterface (expr_type, TypeManager.idisposable_type)){
+                               conv = Convert.ImplicitConversionRequired (
+                                       ec, expr, TypeManager.idisposable_type, loc);
+
+                               if (conv == null)
+                                       return false;
+                       }
+
+                       return true;
+               }
+               
+               //
+               // Emits the code for the case of using using a local variable declaration.
+               //
+               void EmitLocalVariableDecls (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       int i = 0;
+
+                       for (i = 0; i < assign.Length; i++) {
+                               assign [i].EmitStatement (ec);
+
+                               if (emit_finally)
+                                       ig.BeginExceptionBlock ();
+                       }
+                       Statement.Emit (ec);
+
+                       var_list.Reverse ();
+
+                       DoEmitFinally (ec);
+               }
+
+               void EmitLocalVariableDeclFinally (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       int i = assign.Length;
+                       foreach (DictionaryEntry e in var_list){
+                               Expression var = resolved_vars [--i];
+                               Label skip = ig.DefineLabel ();
+                               
+                               ig.BeginFinallyBlock ();
+                               
+                               if (!var.Type.IsValueType) {
+                                       var.Emit (ec);
+                                       ig.Emit (OpCodes.Brfalse, skip);
+                                       converted_vars [i].Emit (ec);
+                                       ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+                               } else {
+                                       Expression ml = Expression.MemberLookup(ec, TypeManager.idisposable_type, var.Type, "Dispose", Mono.CSharp.Location.Null);
+
+                                       if (!(ml is MethodGroupExpr)) {
+                                               var.Emit (ec);
+                                               ig.Emit (OpCodes.Box, var.Type);
+                                               ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+                                       } else {
+                                               MethodInfo mi = null;
+
+                                               foreach (MethodInfo mk in ((MethodGroupExpr) ml).Methods) {
+                                                       if (TypeManager.GetArgumentTypes (mk).Length == 0) {
+                                                               mi = mk;
+                                                               break;
+                                                       }
+                                               }
+
+                                               if (mi == null) {
+                                                       Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
+                                                       return;
+                                               }
+
+                                               IMemoryLocation mloc = (IMemoryLocation) var;
+
+                                               mloc.AddressOf (ec, AddressOp.Load);
+                                               ig.Emit (OpCodes.Call, mi);
+                                       }
+                               }
+
+                               ig.MarkLabel (skip);
+
+                               if (emit_finally) {
+                                       ig.EndExceptionBlock ();
+                                       if (i > 0)
+                                               ig.BeginFinallyBlock ();
+                               }
+                       }
+               }
+
+               void EmitExpression (EmitContext ec)
+               {
+                       //
+                       // Make a copy of the expression and operate on that.
+                       //
+                       ILGenerator ig = ec.ig;
+                       local_copy = ig.DeclareLocal (expr_type);
+                       if (conv != null)
+                               conv.Emit (ec);
+                       else
+                               expr.Emit (ec);
+                       ig.Emit (OpCodes.Stloc, local_copy);
+
+                       if (emit_finally)
+                               ig.BeginExceptionBlock ();
+
+                       Statement.Emit (ec);
+                       
+                       DoEmitFinally (ec);
+                       if (emit_finally)
+                               ig.EndExceptionBlock ();
+               }
+
+               void EmitExpressionFinally (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       if (!local_copy.LocalType.IsValueType) {
+                               Label skip = ig.DefineLabel ();
+                               ig.Emit (OpCodes.Ldloc, local_copy);
+                               ig.Emit (OpCodes.Brfalse, skip);
+                               ig.Emit (OpCodes.Ldloc, local_copy);
+                               ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+                               ig.MarkLabel (skip);
+                       } else {
+                               Expression ml = Expression.MemberLookup(ec, TypeManager.idisposable_type, local_copy.LocalType, "Dispose", Mono.CSharp.Location.Null);
+
+                               if (!(ml is MethodGroupExpr)) {
+                                       ig.Emit (OpCodes.Ldloc, local_copy);
+                                       ig.Emit (OpCodes.Box, local_copy.LocalType);
+                                       ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+                               } else {
+                                       MethodInfo mi = null;
+
+                                       foreach (MethodInfo mk in ((MethodGroupExpr) ml).Methods) {
+                                               if (TypeManager.GetArgumentTypes (mk).Length == 0) {
+                                                       mi = mk;
+                                                       break;
+                                               }
+                                       }
+
+                                       if (mi == null) {
+                                               Report.Error(-100, Mono.CSharp.Location.Null, "Internal error: No Dispose method which takes 0 parameters.");
+                                               return;
+                                       }
+
+                                       ig.Emit (OpCodes.Ldloca, local_copy);
+                                       ig.Emit (OpCodes.Call, mi);
+                               }
+                       }
+               }
+               
+               public override bool Resolve (EmitContext ec)
+               {
+                       if (expression_or_block is DictionaryEntry){
+                               expr = (Expression) ((DictionaryEntry) expression_or_block).Key;
+                               var_list = (ArrayList)((DictionaryEntry)expression_or_block).Value;
+
+                               if (!ResolveLocalVariableDecls (ec))
+                                       return false;
+
+                       } else if (expression_or_block is Expression){
+                               expr = (Expression) expression_or_block;
+
+                               expr = expr.Resolve (ec);
+                               if (expr == null)
+                                       return false;
+
+                               expr_type = expr.Type;
+
+                               if (!ResolveExpression (ec))
+                                       return false;
+                       }
+
+                       FlowBranchingException branching = ec.StartFlowBranching (this);
+
+                       bool ok = Statement.Resolve (ec);
+
+                       if (!ok) {
+                               ec.KillFlowBranching ();
+                               return false;
+                       }
+
+                       ResolveFinally (branching);                                     
+                       FlowBranching.Reachability reachability = ec.EndFlowBranching ();
+
+                       if (reachability.Returns != FlowBranching.FlowReturns.Always) {
+                               // Unfortunately, System.Reflection.Emit automatically emits a leave
+                               // 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.
+                               ec.NeedReturnLabel ();
+                       }
+
+                       return true;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       if (expression_or_block is DictionaryEntry)
+                               EmitLocalVariableDecls (ec);
+                       else if (expression_or_block is Expression)
+                               EmitExpression (ec);
+               }
+
+               public override void EmitFinally (EmitContext ec)
+               {
+                       if (expression_or_block is DictionaryEntry)
+                               EmitLocalVariableDeclFinally (ec);
+                       else if (expression_or_block is Expression)
+                               EmitExpressionFinally (ec);
+               }
+       }
+
+       /// <summary>
+       ///   Implementation of the foreach C# statement
+       /// </summary>
+       public class Foreach : ExceptionStatement {
+               Expression type;
+               Expression variable;
+               Expression expr;
+               Statement statement;
+               ForeachHelperMethods hm;
+               Expression empty, conv;
+               Type array_type, element_type;
+               Type var_type;
+               VariableStorage enumerator;
+               
+               public Foreach (Expression type, LocalVariableReference var, Expression expr,
+                               Statement stmt, Location l)
+               {
+                       this.type = type;
+                       this.variable = var;
+                       this.expr = expr;
+                       statement = stmt;
+                       loc = l;
+               }
+               
+               public override bool Resolve (EmitContext ec)
+               {
+                       expr = expr.Resolve (ec);
+                       if (expr == null)
+                               return false;
+
+                       TypeExpr texpr = type.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return false;
+                       
+                       var_type = texpr.Type;
+
+                       //
+                       // We need an instance variable.  Not sure this is the best
+                       // way of doing this.
+                       //
+                       // FIXME: When we implement propertyaccess, will those turn
+                       // out to return values in ExprClass?  I think they should.
+                       //
+                       if (!(expr.eclass == ExprClass.Variable || expr.eclass == ExprClass.Value ||
+                             expr.eclass == ExprClass.PropertyAccess || expr.eclass == ExprClass.IndexerAccess)){
+                               error1579 (expr.Type);
+                               return false;
+                       }
+
+                       if (expr.Type.IsArray) {
+                               array_type = expr.Type;
+                               element_type = TypeManager.GetElementType (array_type);
+
+                               empty = new EmptyExpression (element_type);
+                       } else {
+                               hm = ProbeCollectionType (ec, expr.Type);
+                               if (hm == null){
+                                       error1579 (expr.Type);
+                                       return false;
+                               }                       
+
+                               array_type = expr.Type;
+                               element_type = hm.element_type;
+
+                               empty = new EmptyExpression (hm.element_type);
+                       }
+
+                       bool ok = true;
+
+                       ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
+                       ec.CurrentBranching.CreateSibling ();
+
+                       //
+                       //
+                       // FIXME: maybe we can apply the same trick we do in the
+                       // array handling to avoid creating empty and conv in some cases.
+                       //
+                       // Although it is not as important in this case, as the type
+                       // will not likely be object (what the enumerator will return).
+                       //
+                       conv = Convert.ExplicitConversion (ec, empty, var_type, loc);
+                       if (conv == null)
+                               ok = false;
+
+                       variable = variable.ResolveLValue (ec, empty);
+                       if (variable == null)
+                               ok = false;
+
+                       bool disposable = (hm != null) && hm.is_disposable;
+                       FlowBranchingException branching = null;
+                       if (disposable)
+                               branching = ec.StartFlowBranching (this);
+
+                       if (!statement.Resolve (ec))
+                               ok = false;
+
+                       if (disposable) {
+                               ResolveFinally (branching);
+                               ec.EndFlowBranching ();
+                       } else
+                               emit_finally = true;
+
+                       ec.EndFlowBranching ();
+
+                       return ok;
+               }
+               
+               //
+               // Retrieves a `public bool MoveNext ()' method from the Type `t'
+               //
+               static MethodInfo FetchMethodMoveNext (Type t)
+               {
+                       MemberList move_next_list;
+                       
+                       move_next_list = TypeContainer.FindMembers (
+                               t, MemberTypes.Method,
+                               BindingFlags.Public | BindingFlags.Instance,
+                               Type.FilterName, "MoveNext");
+                       if (move_next_list.Count == 0)
+                               return null;
+
+                       foreach (MemberInfo m in move_next_list){
+                               MethodInfo mi = (MethodInfo) m;
+                               Type [] args;
+                               
+                               args = TypeManager.GetArgumentTypes (mi);
+                               if (args != null && args.Length == 0){
+                                       if (TypeManager.TypeToCoreType (mi.ReturnType) == TypeManager.bool_type)
+                                               return mi;
+                               }
+                       }
+                       return null;
+               }
+               
+               //
+               // Retrieves a `public T get_Current ()' method from the Type `t'
+               //
+               static MethodInfo FetchMethodGetCurrent (Type t)
+               {
+                       MemberList get_current_list;
+
+                       get_current_list = TypeContainer.FindMembers (
+                               t, MemberTypes.Method,
+                               BindingFlags.Public | BindingFlags.Instance,
+                               Type.FilterName, "get_Current");
+                       if (get_current_list.Count == 0)
+                               return null;
+
+                       foreach (MemberInfo m in get_current_list){
+                               MethodInfo mi = (MethodInfo) m;
+                               Type [] args;
+
+                               args = TypeManager.GetArgumentTypes (mi);
+                               if (args != null && args.Length == 0)
+                                       return mi;
+                       }
+                       return null;
+               }
+
+               // 
+               // Retrieves a `public void Dispose ()' method from the Type `t'
+               //
+               static MethodInfo FetchMethodDispose (Type t)
+               {
+                       MemberList dispose_list;
+                       
+                       dispose_list = TypeContainer.FindMembers (
+                               t, MemberTypes.Method,
+                               BindingFlags.Public | BindingFlags.Instance,
+                               Type.FilterName, "Dispose");
+                       if (dispose_list.Count == 0)
+                               return null;
+
+                       foreach (MemberInfo m in dispose_list){
+                               MethodInfo mi = (MethodInfo) m;
+                               Type [] args;
+                               
+                               args = TypeManager.GetArgumentTypes (mi);
+                               if (args != null && args.Length == 0){
+                                       if (mi.ReturnType == TypeManager.void_type)
+                                               return mi;
+                               }
+                       }
+                       return null;
+               }
+
+               // 
+               // This struct records the helper methods used by the Foreach construct
+               //
+               class ForeachHelperMethods {
+                       public EmitContext ec;
+                       public MethodInfo get_enumerator;
+                       public MethodInfo move_next;
+                       public MethodInfo get_current;
+                       public Type element_type;
+                       public Type enumerator_type;
+                       public bool is_disposable;
+
+                       public ForeachHelperMethods (EmitContext ec)
+                       {
+                               this.ec = ec;
+                               this.element_type = TypeManager.object_type;
+                               this.enumerator_type = TypeManager.ienumerator_type;
+                               this.is_disposable = true;
+                       }
+               }
+               
+               static bool GetEnumeratorFilter (MemberInfo m, object criteria)
+               {
+                       if (m == null)
+                               return false;
+
+                       if (!(m is MethodInfo))
+                               return false;
+                       
+                       if (m.Name != "GetEnumerator")
+                               return false;
+
+                       MethodInfo mi = (MethodInfo) m;
+                       Type [] args = TypeManager.GetArgumentTypes (mi);
+                       if (args != null){
+                               if (args.Length != 0)
+                                       return false;
+                       }
+                       ForeachHelperMethods hm = (ForeachHelperMethods) criteria;
+                       EmitContext ec = hm.ec;
+
+                       // Check whether GetEnumerator is public
+                       if ((mi.Attributes & MethodAttributes.Public) != MethodAttributes.Public)
+                                       return false;
+
+                       if ((mi.ReturnType == TypeManager.ienumerator_type) && (mi.DeclaringType == TypeManager.string_type))
+                               //
+                               // Apply the same optimization as MS: skip the GetEnumerator
+                               // returning an IEnumerator, and use the one returning a 
+                               // CharEnumerator instead. This allows us to avoid the 
+                               // try-finally block and the boxing.
+                               //
+                               return false;
+
+                       //
+                       // Ok, we can access it, now make sure that we can do something
+                       // with this `GetEnumerator'
+                       //
+
+                       Type return_type = mi.ReturnType;
+                       if (mi.ReturnType == TypeManager.ienumerator_type ||
+                           TypeManager.ienumerator_type.IsAssignableFrom (return_type) ||
+                           (!RootContext.StdLib && TypeManager.ImplementsInterface (return_type, TypeManager.ienumerator_type))) {
+                               
+                               //
+                               // If it is not an interface, lets try to find the methods ourselves.
+                               // For example, if we have:
+                               // public class Foo : IEnumerator { public bool MoveNext () {} public int Current { get {}}}
+                               // We can avoid the iface call. This is a runtime perf boost.
+                               // even bigger if we have a ValueType, because we avoid the cost
+                               // of boxing.
+                               //
+                               // We have to make sure that both methods exist for us to take
+                               // this path. If one of the methods does not exist, we will just
+                               // use the interface. Sadly, this complex if statement is the only
+                               // way I could do this without a goto
+                               //
+                               
+                               if (return_type.IsInterface ||
+                                   (hm.move_next = FetchMethodMoveNext (return_type)) == null ||
+                                   (hm.get_current = FetchMethodGetCurrent (return_type)) == null) {
+                                       
+                                       hm.move_next = TypeManager.bool_movenext_void;
+                                       hm.get_current = TypeManager.object_getcurrent_void;
+                                       return true;    
+                               }
+
+                       } else {
+
+                               //
+                               // Ok, so they dont return an IEnumerable, we will have to
+                               // find if they support the GetEnumerator pattern.
+                               //
+                               
+                               hm.move_next = FetchMethodMoveNext (return_type);
+                               if (hm.move_next == null)
+                                       return false;
+                               
+                               hm.get_current = FetchMethodGetCurrent (return_type);
+                               if (hm.get_current == null)
+                                       return false;
+                       }
+                       
+                       hm.element_type = hm.get_current.ReturnType;
+                       hm.enumerator_type = return_type;
+                       hm.is_disposable = !hm.enumerator_type.IsSealed ||
+                               TypeManager.ImplementsInterface (
+                                       hm.enumerator_type, TypeManager.idisposable_type);
+
+                       return true;
+               }
+               
+               /// <summary>
+               ///   This filter is used to find the GetEnumerator method
+               ///   on which IEnumerator operates
+               /// </summary>
+               static MemberFilter FilterEnumerator;
+               
+               static Foreach ()
+               {
+                       FilterEnumerator = new MemberFilter (GetEnumeratorFilter);
+               }
+
+                void error1579 (Type t)
+                {
+                        Report.Error (1579, loc,
+                                      "foreach statement cannot operate on variables of type `" +
+                                      t.FullName + "' because that class does not provide a " +
+                                      " GetEnumerator method or it is inaccessible");
+                }
+
+               static bool TryType (Type t, ForeachHelperMethods hm)
+               {
+                       MemberList mi;
+                       
+                       mi = TypeContainer.FindMembers (t, MemberTypes.Method,
+                                                       BindingFlags.Public | BindingFlags.NonPublic |
+                                                       BindingFlags.Instance | BindingFlags.DeclaredOnly,
+                                                       FilterEnumerator, hm);
+
+                       if (mi.Count == 0)
+                               return false;
+
+                       hm.get_enumerator = (MethodInfo) mi [0];
+                       return true;    
+               }
+               
+               //
+               // Looks for a usable GetEnumerator in the Type, and if found returns
+               // the three methods that participate: GetEnumerator, MoveNext and get_Current
+               //
+               ForeachHelperMethods ProbeCollectionType (EmitContext ec, Type t)
+               {
+                       ForeachHelperMethods hm = new ForeachHelperMethods (ec);
+
+                       for (Type tt = t; tt != null && tt != TypeManager.object_type;){
+                               if (TryType (tt, hm))
+                                       return hm;
+                               tt = tt.BaseType;
+                       }
+
+                       //
+                       // Now try to find the method in the interfaces
+                       //
+                       while (t != null){
+                               Type [] ifaces = t.GetInterfaces ();
+
+                               foreach (Type i in ifaces){
+                                       if (TryType (i, hm))
+                                               return hm;
+                               }
+                               
+                               //
+                               // Since TypeBuilder.GetInterfaces only returns the interface
+                               // types for this type, we have to keep looping, but once
+                               // we hit a non-TypeBuilder (ie, a Type), then we know we are
+                               // done, because it returns all the types
+                               //
+                               if ((t is TypeBuilder))
+                                       t = t.BaseType;
+                               else
+                                       break;
+                       } 
+
+                       return null;
+               }
+
+               //
+               // FIXME: possible optimization.
+               // We might be able to avoid creating `empty' if the type is the sam
+               //
+               bool EmitCollectionForeach (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       enumerator = new VariableStorage (ec, hm.enumerator_type);
+                       enumerator.EmitThis (ig);
+                       //
+                       // Instantiate the enumerator
+                       //
+                       if (expr.Type.IsValueType){
+                               IMemoryLocation ml = expr as IMemoryLocation;
+                               // Load the address of the value type.
+                               if (ml == null) {
+                                       // This happens if, for example, you have a property
+                                       // returning a struct which is IEnumerable
+                                       LocalBuilder t = ec.GetTemporaryLocal (expr.Type);
+                                               expr.Emit(ec);
+                                       ig.Emit (OpCodes.Stloc, t);
+                                       ig.Emit (OpCodes.Ldloca, t);
+                                       ec.FreeTemporaryLocal (t, expr.Type);
+                                       } else {
+                                               ml.AddressOf (ec, AddressOp.Load);
+                                       }
+                               
+                               // Emit the call.
+                               if (hm.get_enumerator.DeclaringType.IsValueType) {
+                                       // the method is declared on the value type
+                                       ig.Emit (OpCodes.Call, hm.get_enumerator);
+                               } else {
+                                       // it is an interface method, so we must box
+                                       ig.Emit (OpCodes.Box, expr.Type);
+                               ig.Emit (OpCodes.Callvirt, hm.get_enumerator);
+                               }
+                       } else {
+                               expr.Emit (ec);
+                               ig.Emit (OpCodes.Callvirt, hm.get_enumerator);
+                       }
+                       enumerator.EmitStore (ig);
+
+                       //
+                       // Protect the code in a try/finalize block, so that
+                       // if the beast implement IDisposable, we get rid of it
+                       //
+                       if (hm.is_disposable && emit_finally)
+                               ig.BeginExceptionBlock ();
+                       
+                       Label end_try = ig.DefineLabel ();
+                       
+                       ig.MarkLabel (ec.LoopBegin);
+                       
+                       enumerator.EmitCall (ig, hm.move_next);
+                       
+                       ig.Emit (OpCodes.Brfalse, end_try);
+
+                       if (ec.InIterator)
+                               enumerator.EmitThis (ig);
+                       enumerator.EmitCall (ig, hm.get_current);
+
+                       if (ec.InIterator){
+                               conv.Emit (ec);
+                               ig.Emit (OpCodes.Stfld, ((LocalVariableReference) variable).local_info.FieldBuilder);
+                       } else 
+                               ((IAssignMethod)variable).EmitAssign (ec, conv, false, false);
+                               
+                       statement.Emit (ec);
+                       ig.Emit (OpCodes.Br, ec.LoopBegin);
+                       ig.MarkLabel (end_try);
+                       
+                       // The runtime provides this for us.
+                       // ig.Emit (OpCodes.Leave, end);
+
+                       //
+                       // Now the finally block
+                       //
+                       if (hm.is_disposable) {
+                               DoEmitFinally (ec);
+                               if (emit_finally)
+                                       ig.EndExceptionBlock ();
+                       }
+
+                       ig.MarkLabel (ec.LoopEnd);
+                       return false;
+               }
+
+               public override void EmitFinally (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+
+                       if (hm.enumerator_type.IsValueType) {
+                               enumerator.EmitThis (ig);
+
+                               MethodInfo mi = FetchMethodDispose (hm.enumerator_type);
+                               if (mi != null) {
+                                       enumerator.EmitLoadAddress (ig);
+                                       ig.Emit (OpCodes.Call, mi);
+                               } else {
+                                       enumerator.EmitLoad (ig);
+                                       ig.Emit (OpCodes.Box, hm.enumerator_type);
+                                       ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+                               }
+                       } else {
+                               Label call_dispose = ig.DefineLabel ();
+
+                               enumerator.EmitThis (ig);
+                               enumerator.EmitLoad (ig);
+                               ig.Emit (OpCodes.Isinst, TypeManager.idisposable_type);
+                               ig.Emit (OpCodes.Dup);
+                               ig.Emit (OpCodes.Brtrue_S, call_dispose);
+                               ig.Emit (OpCodes.Pop);
+
+                               Label end_finally = ig.DefineLabel ();
+                               ig.Emit (OpCodes.Br, end_finally);
+
+                               ig.MarkLabel (call_dispose);
+                               ig.Emit (OpCodes.Callvirt, TypeManager.void_dispose_void);
+                               ig.MarkLabel (end_finally);
+
+                               if (emit_finally)
+                                       ig.Emit (OpCodes.Endfinally);
+                       }
+               }
+
+               //
+               // FIXME: possible optimization.
+               // We might be able to avoid creating `empty' if the type is the sam
+               //
+               bool EmitArrayForeach (EmitContext ec)
+               {
+                       int rank = array_type.GetArrayRank ();
+                       ILGenerator ig = ec.ig;
+
+                       VariableStorage copy = new VariableStorage (ec, array_type);
+                       
+                       //
+                       // Make our copy of the array
+                       //
+                       copy.EmitThis (ig);
+                       expr.Emit (ec);
+                       copy.EmitStore (ig);
+                       
+                       if (rank == 1){
+                               VariableStorage counter = new VariableStorage (ec,TypeManager.int32_type);
+
+                               Label loop, test;
+
+                               counter.EmitThis (ig);
+                               ig.Emit (OpCodes.Ldc_I4_0);
+                               counter.EmitStore (ig);
+                               test = ig.DefineLabel ();
+                               ig.Emit (OpCodes.Br, test);
+
+                               loop = ig.DefineLabel ();
+                               ig.MarkLabel (loop);
+
+                               if (ec.InIterator)
+                                       ec.EmitThis ();
+                               
+                               copy.EmitThis (ig);
+                               copy.EmitLoad (ig);
+                               counter.EmitThis (ig);
+                               counter.EmitLoad (ig);
+
+                               //
+                               // Load the value, we load the value using the underlying type,
+                               // then we use the variable.EmitAssign to load using the proper cast.
+                               //
+                               ArrayAccess.EmitLoadOpcode (ig, element_type);
+                               if (ec.InIterator){
+                                       conv.Emit (ec);
+                                       ig.Emit (OpCodes.Stfld, ((LocalVariableReference) variable).local_info.FieldBuilder);
+                               } else 
+                                       ((IAssignMethod)variable).EmitAssign (ec, conv, false, false);
+
+                               statement.Emit (ec);
+
+                               ig.MarkLabel (ec.LoopBegin);
+                               counter.EmitThis (ig);
+                               counter.EmitThis (ig);
+                               counter.EmitLoad (ig);
+                               ig.Emit (OpCodes.Ldc_I4_1);
+                               ig.Emit (OpCodes.Add);
+                               counter.EmitStore (ig);
+
+                               ig.MarkLabel (test);
+                               counter.EmitThis (ig);
+                               counter.EmitLoad (ig);
+                               copy.EmitThis (ig);
+                               copy.EmitLoad (ig);
+                               ig.Emit (OpCodes.Ldlen);
+                               ig.Emit (OpCodes.Conv_I4);
+                               ig.Emit (OpCodes.Blt, loop);
+                       } else {
+                               VariableStorage [] dim_len   = new VariableStorage [rank];
+                               VariableStorage [] dim_count = new VariableStorage [rank];
+                               Label [] loop = new Label [rank];
+                               Label [] test = new Label [rank];
+                               int dim;
+                               
+                               for (dim = 0; dim < rank; dim++){
+                                       dim_len [dim] = new VariableStorage (ec, TypeManager.int32_type);
+                                       dim_count [dim] = new VariableStorage (ec, TypeManager.int32_type);
+                                       test [dim] = ig.DefineLabel ();
+                                       loop [dim] = ig.DefineLabel ();
+                               }
+                                       
+                               for (dim = 0; dim < rank; dim++){
+                                       dim_len [dim].EmitThis (ig);
+                                       copy.EmitThis (ig);
+                                       copy.EmitLoad (ig);
+                                       IntLiteral.EmitInt (ig, dim);
+                                       ig.Emit (OpCodes.Callvirt, TypeManager.int_getlength_int);
+                                       dim_len [dim].EmitStore (ig);
+                                       
+                               }
+
+                               for (dim = 0; dim < rank; dim++){
+                                       dim_count [dim].EmitThis (ig);
+                                       ig.Emit (OpCodes.Ldc_I4_0);
+                                       dim_count [dim].EmitStore (ig);
+                                       ig.Emit (OpCodes.Br, test [dim]);
+                                       ig.MarkLabel (loop [dim]);
+                               }
+
+                               if (ec.InIterator)
+                                       ec.EmitThis ();
+                               copy.EmitThis (ig);
+                               copy.EmitLoad (ig);
+                               for (dim = 0; dim < rank; dim++){
+                                       dim_count [dim].EmitThis (ig);
+                                       dim_count [dim].EmitLoad (ig);
+                               }
+
+                               //
+                               // FIXME: Maybe we can cache the computation of `get'?
+                               //
+                               Type [] args = new Type [rank];
+                               MethodInfo get;
+
+                               for (int i = 0; i < rank; i++)
+                                       args [i] = TypeManager.int32_type;
+
+                               ModuleBuilder mb = CodeGen.Module.Builder;
+                               get = mb.GetArrayMethod (
+                                       array_type, "Get",
+                                       CallingConventions.HasThis| CallingConventions.Standard,
+                                       var_type, args);
+                               ig.Emit (OpCodes.Call, get);
+                               if (ec.InIterator){
+                                       conv.Emit (ec);
+                                       ig.Emit (OpCodes.Stfld, ((LocalVariableReference) variable).local_info.FieldBuilder);
+                               } else 
+                                       ((IAssignMethod)variable).EmitAssign (ec, conv, false, false);
+                               statement.Emit (ec);
+                               ig.MarkLabel (ec.LoopBegin);
+                               for (dim = rank - 1; dim >= 0; dim--){
+                                       dim_count [dim].EmitThis (ig);
+                                       dim_count [dim].EmitThis (ig);
+                                       dim_count [dim].EmitLoad (ig);
+                                       ig.Emit (OpCodes.Ldc_I4_1);
+                                       ig.Emit (OpCodes.Add);
+                                       dim_count [dim].EmitStore (ig);
+
+                                       ig.MarkLabel (test [dim]);
+                                       dim_count [dim].EmitThis (ig);
+                                       dim_count [dim].EmitLoad (ig);
+                                       dim_len [dim].EmitThis (ig);
+                                       dim_len [dim].EmitLoad (ig);
+                                       ig.Emit (OpCodes.Blt, loop [dim]);
+                               }
+                       }
+                       ig.MarkLabel (ec.LoopEnd);
+                       
+                       return false;
+               }
+               
+               protected override void DoEmit (EmitContext ec)
+               {
+                       ILGenerator ig = ec.ig;
+                       
+                       Label old_begin = ec.LoopBegin, old_end = ec.LoopEnd;
+                       ec.LoopBegin = ig.DefineLabel ();
+                       ec.LoopEnd = ig.DefineLabel ();
+                       
+                       if (hm != null)
+                               EmitCollectionForeach (ec);
+                       else
+                               EmitArrayForeach (ec);
+                       
+                       ec.LoopBegin = old_begin;
+                       ec.LoopEnd = old_end;
+               }
+       }
+}
diff --git a/mcs/bmcs/support.cs b/mcs/bmcs/support.cs
new file mode 100644 (file)
index 0000000..72dd624
--- /dev/null
@@ -0,0 +1,610 @@
+//
+// support.cs: Support routines to work around the fact that System.Reflection.Emit
+// can not introspect types that are being constructed
+//
+// Author:
+//   Miguel de Icaza (miguel@ximian.com)
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+//
+
+using System;
+using System.IO;
+using System.Text;
+using System.Reflection;
+using System.Collections;
+using System.Reflection.Emit;
+using System.Globalization;
+
+namespace Mono.CSharp {
+
+       public interface ParameterData {
+               Type ParameterType (int pos);
+               GenericConstraints GenericConstraints (int pos);
+               int  Count { get; }
+               bool HasParams { get; }
+               string ParameterName (int pos);
+               string ParameterDesc (int pos);
+               Parameter.Modifier ParameterModifier (int pos);
+       }
+
+       public class ReflectionParameters : ParameterData {
+               ParameterInfo [] pi;
+               Type[] type_params;
+               bool last_arg_is_params = false;
+               bool is_varargs = false;
+               ParameterData gpd;
+
+               public ReflectionParameters (MethodBase mb)
+               {
+                       object [] attrs;
+
+                       ParameterInfo [] pi = mb.GetParameters ();
+                       is_varargs = (mb.CallingConvention & CallingConventions.VarArgs) != 0;
+
+                       this.pi = pi;
+                       int count = pi.Length-1;
+
+                       if (count < 0)
+                               return;
+
+                       if (mb.Mono_IsInflatedMethod) {
+                               MethodInfo generic = mb.GetGenericMethodDefinition ();
+                               gpd = Invocation.GetParameterData (generic);
+
+                               last_arg_is_params = gpd.HasParams;
+                               return;
+                       }
+
+                       if (mb.IsGenericMethodDefinition)
+                               type_params = mb.GetGenericArguments ();
+
+                       attrs = pi [count].GetCustomAttributes (TypeManager.param_array_type, true);
+                       if (attrs == null)
+                               return;
+
+                       if (attrs.Length == 0)
+                               return;
+
+                       last_arg_is_params = true;
+               }
+
+               public Type ParameterType (int pos)
+               {
+                       if (last_arg_is_params && pos >= pi.Length - 1)
+                               return pi [pi.Length - 1].ParameterType;
+                       else if (is_varargs && pos >= pi.Length)
+                               return TypeManager.runtime_argument_handle_type;
+                       else {
+                               Type t = pi [pos].ParameterType;
+
+                               return t;
+                       }
+               }
+
+               public GenericConstraints GenericConstraints (int pos)
+               {
+                       if (gpd != null)
+                               return gpd.GenericConstraints (pos);
+
+                       if (type_params == null)
+                               return null;
+
+                       return new ReflectionConstraints (type_params [pos]);
+               }
+
+               public string ParameterName (int pos)
+               {
+                       if (gpd != null)
+                               return gpd.ParameterName (pos);
+
+                       if (last_arg_is_params && pos >= pi.Length - 1)
+                               return pi [pi.Length - 1].Name;
+                       else if (is_varargs && pos >= pi.Length)
+                               return "__arglist";
+                       else 
+                               return pi [pos].Name;
+               }
+
+               public string ParameterDesc (int pos)
+               {
+                       if (is_varargs && pos >= pi.Length)
+                               return "";                      
+
+                       StringBuilder sb = new StringBuilder ();
+
+                       if (pi [pos].IsIn)
+                               sb.Append ("in ");
+
+                       Type partype = ParameterType (pos);
+                       if (partype.IsByRef){
+                               partype = TypeManager.GetElementType (partype);
+                               if (pi [pos].IsOut)
+                                       sb.Append ("out ");
+                               else
+                                       sb.Append ("ref ");
+                       } 
+
+                       if (pos >= pi.Length - 1 && last_arg_is_params)
+                               sb.Append ("params ");
+                       
+                       sb.Append (TypeManager.CSharpName (partype));
+
+                       return sb.ToString ();
+                       
+               }
+
+               public Parameter.Modifier ParameterModifier (int pos)
+               {
+                       int len = pi.Length;
+
+                       if (last_arg_is_params && pos >= pi.Length - 1)
+                                       return Parameter.Modifier.PARAMS;
+                       else if (is_varargs && pos >= pi.Length)
+                               return Parameter.Modifier.ARGLIST;
+                       
+                       if (gpd != null)
+                               return gpd.ParameterModifier (pos);
+
+                       Type t = pi [pos].ParameterType;
+                       if (t.IsByRef){
+                               if ((pi [pos].Attributes & ParameterAttributes.Out) != 0)
+                                       return Parameter.Modifier.ISBYREF | Parameter.Modifier.OUT;
+                               else
+                                       return Parameter.Modifier.ISBYREF | Parameter.Modifier.REF;
+                       }
+                       
+                       return Parameter.Modifier.NONE;
+               }
+
+               public int Count {
+                       get {
+                               return is_varargs ? pi.Length + 1 : pi.Length;
+                       }
+               }
+
+               public bool HasParams {
+                       get {
+                               return this.last_arg_is_params;
+                       }
+               }
+       }
+
+       public class InternalParameters : ParameterData {
+               Type [] param_types;
+               bool has_varargs;
+               int count;
+
+               public readonly Parameters Parameters;
+               public readonly TypeParameter[] TypeParameters;
+               
+               public InternalParameters (Type [] param_types, Parameters parameters)
+               {
+                       this.param_types = param_types;
+                       this.Parameters = parameters;
+
+                       has_varargs = parameters.HasArglist;
+
+                       if (param_types == null)
+                               count = 0;
+                       else
+                               count = param_types.Length;
+               }
+
+               public InternalParameters (Type [] param_types, Parameters parameters,
+                                          TypeParameter [] type_params)
+                       : this (param_types, parameters)
+               {
+                       this.TypeParameters = type_params;
+               }
+
+               public int Count {
+                       get {
+                               return has_varargs ? count + 1 : count;
+                       }
+               }
+
+               public bool HasParams {
+                       get {
+                               return Parameters.ArrayParameter != null;
+                       }
+               }
+
+               Parameter GetParameter (int pos)
+               {
+                       Parameter [] fixed_pars = Parameters.FixedParameters;
+                       if (fixed_pars != null){
+                               int len = fixed_pars.Length;
+                               if (pos < len)
+                                       return Parameters.FixedParameters [pos];
+                       }
+
+                       return Parameters.ArrayParameter;
+               }
+
+               public Type ParameterType (int pos)
+               {
+                       if (has_varargs && pos >= count)
+                               return TypeManager.runtime_argument_handle_type;
+
+                       if (param_types == null)
+                               return null;
+
+                       return GetParameter (pos).ExternalType ();
+               }
+
+               public GenericConstraints GenericConstraints (int pos)
+               {
+                       if (TypeParameters == null)
+                               return null;
+
+                       return TypeParameters [pos].Constraints;
+               }
+
+               public string ParameterName (int pos)
+               {
+                       if (has_varargs && pos >= count)
+                               return "__arglist";
+
+                       return GetParameter (pos).Name;
+               }
+
+               public string ParameterDesc (int pos)
+               {
+                       if (has_varargs && pos >= count)
+                               return "__arglist";
+
+                       string tmp = String.Empty;
+                       Parameter p = GetParameter (pos);
+
+                       //
+                       // We need to and for REF/OUT, because if either is set the
+                       // extra flag ISBYREF will be set as well
+                       //
+                       if ((p.ModFlags & Parameter.Modifier.REF) != 0)
+                               tmp = "ref ";
+                       else if ((p.ModFlags & Parameter.Modifier.OUT) != 0)
+                               tmp = "out ";
+                       else if (p.ModFlags == Parameter.Modifier.PARAMS)
+                               tmp = "params ";
+
+                       Type t = ParameterType (pos);
+
+                       return tmp + TypeManager.CSharpName (t);
+               }
+
+               public Parameter.Modifier ParameterModifier (int pos)
+               {
+                       if (has_varargs && pos >= count)
+                               return Parameter.Modifier.ARGLIST;
+
+                       Parameter.Modifier mod = GetParameter (pos).ModFlags;
+
+                       if ((mod & (Parameter.Modifier.REF | Parameter.Modifier.OUT)) != 0)
+                               mod |= Parameter.Modifier.ISBYREF;
+
+                       return mod;
+               }
+               
+       }
+
+       public class ReflectionConstraints : GenericConstraints
+       {
+               GenericParameterAttributes attrs;
+               Type base_type;
+               Type class_constraint;
+               Type[] iface_constraints;
+
+               public ReflectionConstraints (Type t)
+               {
+                       Type[] constraints = t.GetGenericParameterConstraints ();
+                       if ((constraints.Length > 0) && !constraints [0].IsInterface) {
+                               class_constraint = constraints [0];
+                               iface_constraints = new Type [constraints.Length - 1];
+                               Array.Copy (constraints, 1, iface_constraints, 0, constraints.Length - 1);
+                       } else
+                               iface_constraints = constraints;
+                       attrs = t.GenericParameterAttributes;
+
+                       if (HasValueTypeConstraint)
+                               base_type = TypeManager.value_type;
+                       else if (class_constraint != null)
+                               base_type = class_constraint;
+                       else
+                               base_type = TypeManager.object_type;
+               }
+
+               public override GenericParameterAttributes Attributes {
+                       get { return attrs; }
+               }
+
+               public override Type ClassConstraint {
+                       get { return class_constraint; }
+               }
+
+               public override Type EffectiveBaseClass {
+                       get { return base_type; }
+               }
+
+               public override Type[] InterfaceConstraints {
+                       get { return iface_constraints; }
+               }
+       }
+
+       class PtrHashtable : Hashtable {
+               sealed class PtrComparer : IComparer {
+                       private PtrComparer () {}
+                       
+                       public static PtrComparer Instance = new PtrComparer ();
+                       
+                       public int Compare (object x, object y)
+                       {
+                               if (x == y)
+                                       return 0;
+                               else
+                                       return 1;
+                       }
+               }
+               
+               public PtrHashtable ()
+               {
+                       comparer = PtrComparer.Instance;
+               }
+       }
+
+       /*
+        * Hashtable whose keys are character arrays with the same length
+        */
+       class CharArrayHashtable : Hashtable {
+               sealed class ArrComparer : IComparer {
+                       private int len;
+
+                       public ArrComparer (int len) {
+                               this.len = len;
+                       }
+
+                       public int Compare (object x, object y)
+                       {
+                               char[] a = (char[])x;
+                               char[] b = (char[])y;
+
+                               for (int i = 0; i < len; ++i)
+                                       if (a [i] != b [i])
+                                               return 1;
+                               return 0;
+                       }
+               }
+
+               private int len;
+
+               protected override int GetHash (Object key)
+               {
+                       char[] arr = (char[])key;
+                       int h = 0;
+
+                       for (int i = 0; i < len; ++i)
+                               h = (h << 5) - h + arr [i];
+
+                       return h;
+               }
+
+               public CharArrayHashtable (int len)
+               {
+                       this.len = len;
+                       comparer = new ArrComparer (len);
+               }
+       }                       
+
+       struct Pair {
+               public object First;
+               public object Second;
+               
+               public Pair (object f, object s)
+               {
+                       First = f;
+                       Second = s;
+               }
+       }
+
+       /// <summary>
+       ///   This is a wrapper around StreamReader which is seekable.
+       /// </summary>
+       public class SeekableStreamReader
+       {
+               public SeekableStreamReader (StreamReader reader)
+               {
+                       this.reader = reader;
+                       this.buffer = new char [DefaultCacheSize];
+                       
+                       // Compute the preamble size
+                       
+                       // Let the StreamWriter autodetect the encoder
+                       reader.Peek ();
+                       
+                       reader.BaseStream.Position = 0;
+                       Encoding enc = reader.CurrentEncoding;
+                       // First of all, get at least a char
+                       
+                       byte[] auxb = new byte [50];
+                       int num_bytes = 0;
+                       int num_chars = 0;
+                       int br = 0;
+                       do {
+                               br = reader.BaseStream.Read (auxb, num_bytes, auxb.Length - num_bytes);
+                               num_bytes += br;
+                               num_chars = enc.GetCharCount (auxb, 0, num_bytes);
+                       }
+                       while (num_chars == 0 && br > 0);
+                       
+                       if (num_chars != 0)
+                       {
+                               // Now, check which bytes at the beginning have no effect in the
+                               // char count
+                               
+                               int p = 0;
+                               while (enc.GetCharCount (auxb, p, num_bytes-p) >= num_chars)
+                                       p++;
+                               
+                               preamble_size = p - 1;
+                               reader.BaseStream.Position = 0;
+                               reader.DiscardBufferedData ();
+                               
+                               buffer_start = preamble_size;
+                       }
+               }
+
+               public SeekableStreamReader (Stream stream, Encoding encoding, bool detect_encoding_from_bytemarks)
+                       : this (new StreamReader (stream, encoding, detect_encoding_from_bytemarks))
+               { }
+
+               StreamReader reader;
+
+               private const int DefaultCacheSize = 1024;
+
+               char[] buffer;
+               int buffer_start;       // in bytes
+               int buffer_size;        // in bytes
+               int char_count;         // count buffer[] valid characters
+               int pos;                // index into buffer[]
+               int preamble_size;
+
+               /// <remarks>
+               ///   The difference to the StreamReader's BaseStream.Position is that this one is reliable; ie. it
+               //    always reports the correct position and if it's modified, it also takes care of the buffered data.
+               /// </remarks>
+               public int Position {
+                       get {
+                               return buffer_start + reader.CurrentEncoding.GetByteCount (buffer, 0, pos);
+                       }
+
+                       set {
+                               // This one is easy: we're modifying the position within our current
+                               // buffer.
+                               if ((value >= buffer_start) && (value < buffer_start + buffer_size)) {
+                                       int byte_offset = value - buffer_start;
+                                       pos = byte_offset;
+                                       // encoded characters can take more than 1 byte length
+                                       while (reader.CurrentEncoding.GetByteCount (buffer, 0, pos) > byte_offset)
+                                               pos--;
+                                       
+                                       return;
+                               }
+                               
+                               if (value == 0) // Skip preamble
+                                       value = preamble_size;
+
+                               // Ok, now we need to seek.
+                               reader.DiscardBufferedData ();
+                               reader.BaseStream.Position = buffer_start = value;
+                               char_count = buffer_size = pos = 0;
+                       }
+               }
+
+               private bool ReadBuffer ()
+               {
+                       pos = 0;
+                       buffer_start += buffer_size;
+                       char_count = reader.Read (buffer, 0, buffer.Length);
+                       buffer_size = reader.CurrentEncoding.GetByteCount (buffer, 0, char_count);
+                       return buffer_size > 0;
+               }
+
+               public int Peek ()
+               {
+                       if ((pos >= char_count) && !ReadBuffer ())
+                               return -1;
+
+                       return buffer [pos];
+               }
+
+               public int Read ()
+               {
+                       if ((pos >= char_count) && !ReadBuffer ())
+                               return -1;
+
+                       return buffer [pos++];
+               }
+       }
+
+       public class DoubleHash {
+               const int DEFAULT_INITIAL_BUCKETS = 100;
+               
+               public DoubleHash () : this (DEFAULT_INITIAL_BUCKETS) {}
+               
+               public DoubleHash (int size)
+               {
+                       count = size;
+                       buckets = new Entry [size];
+               }
+               
+               int count;
+               Entry [] buckets;
+               int size = 0;
+               
+               class Entry {
+                       public object key1;
+                       public object key2;
+                       public int hash;
+                       public object value;
+                       public Entry next;
+       
+                       public Entry (object key1, object key2, int hash, object value, Entry next)
+                       {
+                               this.key1 = key1;
+                               this.key2 = key2;
+                               this.hash = hash;
+                               this.next = next;
+                               this.value = value;
+                       }
+               }
+
+               public bool Lookup (object a, object b, out object res)
+               {
+                       int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF;
+                       
+                       for (Entry e = buckets [h % count]; e != null; e = e.next) {
+                               if (e.hash == h && e.key1.Equals (a) && e.key2.Equals (b)) {
+                                       res = e.value;
+                                       return true;
+                               }
+                       }
+                       res = null;
+                       return false;
+               }
+
+               public void Insert (object a, object b, object value)
+               {
+                       // Is it an existing one?
+               
+                       int h = (a.GetHashCode () ^ b.GetHashCode ()) & 0x7FFFFFFF;
+                       
+                       for (Entry e = buckets [h % count]; e != null; e = e.next) {
+                               if (e.hash == h && e.key1.Equals (a) && e.key2.Equals (b))
+                                       e.value = value;
+                       }
+                       
+                       int bucket = h % count;
+                       buckets [bucket] = new Entry (a, b, h, value, buckets [bucket]);
+                       
+                       // Grow whenever we double in size
+                       if (size++ == count) {
+                               count <<= 1;
+                               count ++;
+                               
+                               Entry [] newBuckets = new Entry [count];
+                               foreach (Entry root in buckets) {
+                                       Entry e = root;
+                                       while (e != null) {
+                                               int newLoc = e.hash % count;
+                                               Entry n = e.next;
+                                               e.next = newBuckets [newLoc];
+                                               newBuckets [newLoc] = e;
+                                               e = n;
+                                       }
+                               }
+
+                               buckets = newBuckets;
+                       }
+               }
+       }
+}
diff --git a/mcs/bmcs/symbolwriter.cs b/mcs/bmcs/symbolwriter.cs
new file mode 100644 (file)
index 0000000..cebbe40
--- /dev/null
@@ -0,0 +1,91 @@
+//
+// symbolwriter.cs: The symbol writer
+//
+// Author:
+//   Martin Baulig (martin@ximian.com)
+//
+// (C) 2003 Ximian, Inc.
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+
+using Mono.CompilerServices.SymbolWriter;
+
+namespace Mono.CSharp {
+       public class SymbolWriter : MonoSymbolWriter {
+               delegate int GetILOffsetFunc (ILGenerator ig);
+               delegate Guid GetGuidFunc (ModuleBuilder mb);
+
+               GetILOffsetFunc get_il_offset_func;
+               GetGuidFunc get_guid_func;
+
+               ModuleBuilder module_builder;
+
+               protected SymbolWriter (ModuleBuilder module_builder, string filename)
+                       : base (filename)
+               {
+                       this.module_builder = module_builder;
+               }
+
+               bool Initialize ()
+               {
+                       MethodInfo mi = typeof (ILGenerator).GetMethod (
+                               "Mono_GetCurrentOffset",
+                               BindingFlags.Static | BindingFlags.NonPublic);
+                       if (mi == null)
+                               return false;
+
+                       get_il_offset_func = (GetILOffsetFunc) System.Delegate.CreateDelegate (
+                               typeof (GetILOffsetFunc), mi);
+
+                       mi = typeof (ModuleBuilder).GetMethod (
+                               "Mono_GetGuid",
+                               BindingFlags.Static | BindingFlags.NonPublic);
+                       if (mi == null)
+                               return false;
+
+                       get_guid_func = (GetGuidFunc) System.Delegate.CreateDelegate (
+                               typeof (GetGuidFunc), mi);
+
+                       Location.DefineSymbolDocuments (this);
+                       Namespace.DefineNamespaces (this);
+
+                       return true;
+               }
+
+               public void DefineLocalVariable (string name, LocalBuilder builder)
+               {
+                       SignatureHelper sighelper = SignatureHelper.GetLocalVarSigHelper (
+                               module_builder);
+                       sighelper.AddArgument (builder.LocalType);
+                       byte[] signature = sighelper.GetSignature ();
+
+                       DefineLocalVariable (name, signature);
+               }
+
+               public void MarkSequencePoint (ILGenerator ig, int row, int column)
+               {
+                       int offset = get_il_offset_func (ig);
+                       MarkSequencePoint (offset, row, column);
+               }
+
+               public void WriteSymbolFile ()
+               {
+                       Guid guid = get_guid_func (module_builder);
+                       WriteSymbolFile (guid);
+               }
+
+               public static SymbolWriter GetSymbolWriter (ModuleBuilder module,
+                                                           string filename)
+               {
+                       SymbolWriter writer = new SymbolWriter (module, filename);
+                       if (!writer.Initialize ())
+                               return null;
+
+                       return writer;
+               }
+       }
+}
diff --git a/mcs/bmcs/tree.cs b/mcs/bmcs/tree.cs
new file mode 100644 (file)
index 0000000..60394d4
--- /dev/null
@@ -0,0 +1,129 @@
+//
+// tree.cs: keeps a tree representation of the generated code
+//
+// Author: Miguel de Icaza (miguel@gnu.org)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+//
+//
+
+using System;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.IO;
+
+namespace Mono.CSharp
+{
+
+       public interface ITreeDump {
+               int  Dump (Tree tree, StreamWriter output);
+               void ParseOptions (string options);
+       }
+
+       // <summary>
+       //   
+       //   We store here all the toplevel types that we have parsed,
+       //   this is the root of all information we have parsed.
+       // 
+       // </summary>
+       
+       public class Tree {
+               TypeContainer root_types;
+
+               // <summary>
+               //   Keeps track of all the types definied (classes, structs, ifaces, enums)
+               // </summary>
+               Hashtable decls;
+               
+               public Tree ()
+               {
+                       root_types = new RootTypes ();
+
+                       decls = new Hashtable ();
+               }
+
+               DoubleHash decl_ns_name = new DoubleHash ();
+               
+               public void RecordDecl (string name, DeclSpace ds)
+               {
+                       DeclSpace other = (DeclSpace) decls [name];
+                       if (other != null){
+                               PartialContainer other_pc = other as PartialContainer;
+                               if ((ds is TypeContainer) && (other_pc != null)) {
+                                       Report.Error (
+                                               260, ds.Location, "Missing partial modifier " +
+                                               "on declaration of type `{0}'; another " +
+                                               "partial implementation of this type exists",
+                                               name);
+
+                                       Report.LocationOfPreviousError (other.Location);
+                                       return;
+                               }
+
+                               Report.SymbolRelatedToPreviousError (
+                                       other.Location, other.GetSignatureForError ());
+
+                               Report.Error (
+                                       101, ds.Location,
+                                       "There is already a definition for `" + name + "'");
+                               return;
+                       }
+
+                       ds.RecordDecl ();
+
+                       int p = name.LastIndexOf ('.');
+                       if (p == -1)
+                               decl_ns_name.Insert ("", name, ds);
+                       else {
+                               decl_ns_name.Insert (name.Substring (0, p), name.Substring (p+1), ds);
+                       }
+
+                       decls.Add (name, ds);
+               }
+
+               public DeclSpace LookupByNamespace (string ns, string name)
+               {
+                       object res;
+                       
+                       decl_ns_name.Lookup (ns, name, out res);
+                       return (DeclSpace) res;
+               }
+               
+               //
+               // FIXME: Why are we using Types?
+               //
+                public TypeContainer Types {
+                        get {
+                                return root_types;
+                        }
+                }
+
+               public Hashtable Decls {
+                       get {
+                               return decls;
+                       }
+               }
+       }
+
+       public class RootTypes : TypeContainer
+       {
+               public RootTypes ()
+                       : base (null, null, MemberName.Null, null, Kind.Root, Location.Null)
+               {
+                       ec = new EmitContext (null, this, Location.Null, null, null, 0, false);
+               }
+
+               public override void Register ()
+               {
+                       throw new InvalidOperationException ();
+                       }
+
+               public override PendingImplementation GetPendingImplementations ()
+               {
+                       throw new InvalidOperationException ();
+               }
+       }
+}
diff --git a/mcs/bmcs/typemanager.cs b/mcs/bmcs/typemanager.cs
new file mode 100644 (file)
index 0000000..6b40712
--- /dev/null
@@ -0,0 +1,3179 @@
+//
+// typemanager.cs: C# type manager
+//
+// Author: Miguel de Icaza (miguel@gnu.org)
+//         Ravi Pratap     (ravi@ximian.com)
+//
+// Licensed under the terms of the GNU GPL
+//
+// (C) 2001 Ximian, Inc (http://www.ximian.com)
+//
+//
+
+//
+// We will eventually remove the SIMPLE_SPEEDUP, and should never change 
+// the behavior of the compilation.  This can be removed if we rework
+// the code to get a list of namespaces available.
+//
+#define SIMPLE_SPEEDUP
+
+using System;
+using System.IO;
+using System.Globalization;
+using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Runtime.CompilerServices;
+using System.Diagnostics;
+
+namespace Mono.CSharp {
+
+public partial class TypeManager {
+       //
+       // A list of core types that the compiler requires or uses
+       //
+       static public Type object_type;
+       static public Type value_type;
+       static public Type string_type;
+       static public Type int32_type;
+       static public Type uint32_type;
+       static public Type int64_type;
+       static public Type uint64_type;
+       static public Type float_type;
+       static public Type double_type;
+       static public Type char_type;
+       static public Type char_ptr_type;
+       static public Type short_type;
+       static public Type decimal_type;
+       static public Type bool_type;
+       static public Type sbyte_type;
+       static public Type byte_type;
+       static public Type ushort_type;
+       static public Type enum_type;
+       static public Type delegate_type;
+       static public Type multicast_delegate_type;
+       static public Type void_type;
+       static public Type null_type;
+       static public Type enumeration_type;
+       static public Type array_type;
+       static public Type runtime_handle_type;
+       static public Type icloneable_type;
+       static public Type type_type;
+       static public Type ienumerator_type;
+       static public Type ienumerable_type;
+       static public Type idisposable_type;
+       static public Type iconvertible_type;
+       static public Type default_member_type;
+       static public Type iasyncresult_type;
+       static public Type asynccallback_type;
+       static public Type intptr_type;
+       static public Type monitor_type;
+       static public Type runtime_field_handle_type;
+       static public Type runtime_argument_handle_type;
+       static public Type attribute_type;
+       static public Type attribute_usage_type;
+       static public Type decimal_constant_attribute_type;
+       static public Type dllimport_type;
+       static public Type unverifiable_code_type;
+       static public Type methodimpl_attr_type;
+       static public Type marshal_as_attr_type;
+       static public Type param_array_type;
+       static public Type guid_attr_type;
+       static public Type void_ptr_type;
+       static public Type indexer_name_type;
+       static public Type exception_type;
+       static public Type invalid_operation_exception_type;
+       static public Type not_supported_exception_type;
+       static public Type obsolete_attribute_type;
+       static public Type conditional_attribute_type;
+       static public Type in_attribute_type;
+       static public Type anonymous_method_type;
+       static public Type cls_compliant_attribute_type;
+       static public Type typed_reference_type;
+       static public Type arg_iterator_type;
+       static public Type mbr_type;
+       static public Type struct_layout_attribute_type;
+       static public Type field_offset_attribute_type;
+       static public Type security_attr_type;
+
+       //
+       // An empty array of types
+       //
+       static public Type [] NoTypes;
+       static public TypeExpr [] NoTypeExprs;
+
+
+       // 
+       // Expressions representing the internal types.  Used during declaration
+       // definition.
+       //
+       static public TypeExpr system_object_expr, system_string_expr; 
+       static public TypeExpr system_boolean_expr, system_decimal_expr;
+       static public TypeExpr system_single_expr, system_double_expr;
+       static public TypeExpr system_sbyte_expr, system_byte_expr;
+       static public TypeExpr system_int16_expr, system_uint16_expr;
+       static public TypeExpr system_int32_expr, system_uint32_expr;
+       static public TypeExpr system_int64_expr, system_uint64_expr;
+       static public TypeExpr system_char_expr, system_void_expr;
+       static public TypeExpr system_asynccallback_expr;
+       static public TypeExpr system_iasyncresult_expr;
+       static public TypeExpr system_valuetype_expr;
+       static public TypeExpr system_intptr_expr;
+
+       //
+       // This is only used when compiling corlib
+       //
+       static public Type system_int32_type;
+       static public Type system_array_type;
+       static public Type system_type_type;
+       static public Type system_assemblybuilder_type;
+       static public MethodInfo system_int_array_get_length;
+       static public MethodInfo system_int_array_get_rank;
+       static public MethodInfo system_object_array_clone;
+       static public MethodInfo system_int_array_get_length_int;
+       static public MethodInfo system_int_array_get_lower_bound_int;
+       static public MethodInfo system_int_array_get_upper_bound_int;
+       static public MethodInfo system_void_array_copyto_array_int;
+
+       
+       //
+       // Internal, not really used outside
+       //
+       static Type runtime_helpers_type;
+       
+       //
+       // These methods are called by code generated by the compiler
+       //
+       static public MethodInfo string_concat_string_string;
+       static public MethodInfo string_concat_string_string_string;
+       static public MethodInfo string_concat_string_string_string_string;
+       static public MethodInfo string_concat_string_dot_dot_dot;
+       static public MethodInfo string_concat_object_object;
+       static public MethodInfo string_concat_object_object_object;
+       static public MethodInfo string_concat_object_dot_dot_dot;
+       static public MethodInfo string_isinterneted_string;
+       static public MethodInfo system_type_get_type_from_handle;
+       static public MethodInfo object_getcurrent_void;
+       static public MethodInfo bool_movenext_void;
+       static public MethodInfo ienumerable_getenumerator_void;
+       static public MethodInfo void_reset_void;
+       static public MethodInfo void_dispose_void;
+       static public MethodInfo void_monitor_enter_object;
+       static public MethodInfo void_monitor_exit_object;
+       static public MethodInfo void_initializearray_array_fieldhandle;
+       static public MethodInfo int_getlength_int;
+       static public MethodInfo delegate_combine_delegate_delegate;
+       static public MethodInfo delegate_remove_delegate_delegate;
+       static public MethodInfo int_get_offset_to_string_data;
+       static public MethodInfo int_array_get_length;
+       static public MethodInfo int_array_get_rank;
+       static public MethodInfo object_array_clone;
+       static public MethodInfo int_array_get_length_int;
+       static public MethodInfo int_array_get_lower_bound_int;
+       static public MethodInfo int_array_get_upper_bound_int;
+       static public MethodInfo void_array_copyto_array_int;
+       
+       //
+       // The attribute constructors.
+       //
+       static public ConstructorInfo object_ctor;
+       static public ConstructorInfo cons_param_array_attribute;
+       static public ConstructorInfo void_decimal_ctor_five_args;
+       static public ConstructorInfo void_decimal_ctor_int_arg;
+       static public ConstructorInfo unverifiable_code_ctor;
+       static public ConstructorInfo invalid_operation_ctor;
+       static public ConstructorInfo default_member_ctor;
+       static public ConstructorInfo decimal_constant_attribute_ctor;
+       
+       // <remarks>
+       //   Holds the Array of Assemblies that have been loaded
+       //   (either because it is the default or the user used the
+       //   -r command line option)
+       // </remarks>
+       static Assembly [] assemblies;
+
+       // <remarks>
+       //  Keeps a list of modules. We used this to do lookups
+       //  on the module using GetType -- needed for arrays
+       // </remarks>
+       static Module [] modules;
+
+       // <remarks>
+       //   This is the type_cache from the assemblies to avoid
+       //   hitting System.Reflection on every lookup.
+       // </summary>
+       static Hashtable types;
+
+       // <remarks>
+       //  This is used to hotld the corresponding TypeContainer objects
+       //  since we need this in FindMembers
+       // </remarks>
+       static Hashtable typecontainers;
+
+       // <remarks>
+       //   Keeps track of those types that are defined by the
+       //   user's program
+       // </remarks>
+       static ArrayList user_types;
+
+       static PtrHashtable builder_to_declspace;
+
+       static PtrHashtable builder_to_member_cache;
+
+       // <remarks>
+       //   Tracks the interfaces implemented by typebuilders.  We only
+       //   enter those who do implement or or more interfaces
+       // </remarks>
+       static PtrHashtable builder_to_ifaces;
+
+       // <remarks>
+       //   Maps MethodBase.RuntimeTypeHandle to a Type array that contains
+       //   the arguments to the method
+       // </remarks>
+       static Hashtable method_arguments;
+
+       // <remarks>
+       //   Maps PropertyBuilder to a Type array that contains
+       //   the arguments to the indexer
+       // </remarks>
+       static Hashtable indexer_arguments;
+
+       // <remarks>
+       //   Maybe `method_arguments' should be replaced and only
+       //   method_internal_params should be kept?
+       // <remarks>
+       static Hashtable method_internal_params;
+
+       // <remarks>
+       //  Keeps track of methods
+       // </remarks>
+
+       static Hashtable builder_to_method;
+
+       // <remarks>
+       //  Contains all public types from referenced assemblies.
+       //  This member is used only if CLS Compliance verification is required.
+       // </remarks>
+       public static Hashtable all_imported_types;
+
+       struct Signature {
+               public string name;
+               public Type [] args;
+       }
+
+       public static void CleanUp ()
+       {
+               // Lets get everything clean so that we can collect before generating code
+               assemblies = null;
+               modules = null;
+               types = null;
+               typecontainers = null;
+               user_types = null;
+               builder_to_declspace = null;
+               builder_to_member_cache = null;
+               builder_to_ifaces = null;
+               method_arguments = null;
+               indexer_arguments = null;
+               method_internal_params = null;
+               builder_to_method = null;
+               
+               fields = null;
+               references = null;
+               negative_hits = null;
+               builder_to_constant = null;
+               fieldbuilders_to_fields = null;
+               events = null;
+               priv_fields_events = null;
+               properties = null;
+
+               CleanUpGenerics ();             
+               TypeHandle.CleanUp ();
+       }
+
+       /// <summary>
+       ///   A filter for Findmembers that uses the Signature object to
+       ///   extract objects
+       /// </summary>
+       static bool SignatureFilter (MemberInfo mi, object criteria)
+       {
+               Signature sig = (Signature) criteria;
+
+               if (!(mi is MethodBase))
+                       return false;
+               
+               if (mi.Name != sig.name)
+                       return false;
+
+               int count = sig.args.Length;
+               
+               if (mi is MethodBuilder || mi is ConstructorBuilder){
+                       Type [] candidate_args = GetArgumentTypes ((MethodBase) mi);
+
+                       if (candidate_args.Length != count)
+                               return false;
+                       
+                       for (int i = 0; i < count; i++)
+                               if (candidate_args [i] != sig.args [i])
+                                       return false;
+                       
+                       return true;
+               } else {
+                       ParameterInfo [] pars = ((MethodBase) mi).GetParameters ();
+
+                       if (pars.Length != count)
+                               return false;
+
+                       for (int i = 0; i < count; i++)
+                               if (pars [i].ParameterType != sig.args [i])
+                                       return false;
+                       return true;
+               }
+       }
+
+       // A delegate that points to the filter above.
+       static MemberFilter signature_filter;
+
+       //
+       // These are expressions that represent some of the internal data types, used
+       // elsewhere
+       //
+       static void InitExpressionTypes ()
+       {
+               system_object_expr  = new TypeLookupExpression ("System.Object");
+               system_string_expr  = new TypeLookupExpression ("System.String");
+               system_boolean_expr = new TypeLookupExpression ("System.Boolean");
+               system_decimal_expr = new TypeLookupExpression ("System.Decimal");
+               system_single_expr  = new TypeLookupExpression ("System.Single");
+               system_double_expr  = new TypeLookupExpression ("System.Double");
+               system_sbyte_expr   = new TypeLookupExpression ("System.SByte");
+               system_byte_expr    = new TypeLookupExpression ("System.Byte");
+               system_int16_expr   = new TypeLookupExpression ("System.Int16");
+               system_uint16_expr  = new TypeLookupExpression ("System.UInt16");
+               system_int32_expr   = new TypeLookupExpression ("System.Int32");
+               system_uint32_expr  = new TypeLookupExpression ("System.UInt32");
+               system_int64_expr   = new TypeLookupExpression ("System.Int64");
+               system_uint64_expr  = new TypeLookupExpression ("System.UInt64");
+               system_char_expr    = new TypeLookupExpression ("System.Char");
+               system_void_expr    = new TypeLookupExpression ("System.Void");
+               system_asynccallback_expr = new TypeLookupExpression ("System.AsyncCallback");
+               system_iasyncresult_expr = new TypeLookupExpression ("System.IAsyncResult");
+               system_valuetype_expr  = new TypeLookupExpression ("System.ValueType");
+               system_intptr_expr  = new TypeLookupExpression ("System.IntPtr");
+       }
+
+       static TypeManager ()
+       {
+               assemblies = new Assembly [0];
+               modules = null;
+               user_types = new ArrayList ();
+               
+               types = new Hashtable ();
+               typecontainers = new Hashtable ();
+               
+               builder_to_declspace = new PtrHashtable ();
+               builder_to_member_cache = new PtrHashtable ();
+               builder_to_method = new PtrHashtable ();
+               method_arguments = new PtrHashtable ();
+               method_internal_params = new PtrHashtable ();
+               indexer_arguments = new PtrHashtable ();
+               builder_to_ifaces = new PtrHashtable ();
+               
+               NoTypes = new Type [0];
+               NoTypeExprs = new TypeExpr [0];
+
+               signature_filter = new MemberFilter (SignatureFilter);
+               InitGenerics ();
+               InitExpressionTypes ();
+       }
+
+       public static void HandleDuplicate (string name, Type t)
+       {
+               Type prev = (Type) types [name];
+               TypeContainer tc = builder_to_declspace [prev] as TypeContainer;
+               
+               if (tc != null){
+                       //
+                       // This probably never happens, as we catch this before
+                       //
+                       Report.Error (-17, "The type `" + name + "' has already been defined.");
+                       return;
+               }
+               
+               tc = builder_to_declspace [t] as TypeContainer;
+               if (tc != null){
+                       Report.Warning (
+                                       1595, "The type `" + name + "' is defined in an existing assembly;"+
+                                       " Using the new definition from: " + tc.Location);
+               } else {
+                       Report.Warning (
+                                       1595, "The type `" + name + "' is defined in an existing assembly;");
+               }
+               
+               Report.Warning (1595, "Previously defined in: " + prev.Assembly.FullName);
+               
+               types.Remove (name);
+               types.Add (name, t);
+       }
+       
+       public static void AddUserType (string name, TypeBuilder t)
+       {
+               try {
+                       types.Add (name, t);
+               } catch {
+                       HandleDuplicate (name, t); 
+               }
+               user_types.Add (t);
+       }
+
+       //
+       // This entry point is used by types that we define under the covers
+       // 
+       public static void RegisterBuilder (Type tb, Type [] ifaces)
+       {
+               if (ifaces != null)
+                       builder_to_ifaces [tb] = ifaces;
+       }
+       
+       public static void AddUserType (string name, TypeBuilder t, TypeContainer tc)
+       {
+               builder_to_declspace.Add (t, tc);
+               typecontainers.Add (name, tc);
+               AddUserType (name, t);
+       }
+
+       public static void AddDelegateType (string name, TypeBuilder t, Delegate del)
+       {
+               try {
+                       types.Add (name, t);
+               } catch {
+                       HandleDuplicate (name, t);
+               }
+               
+               builder_to_declspace.Add (t, del);
+       }
+       
+       public static void AddEnumType (string name, TypeBuilder t, Enum en)
+       {
+               try {
+                       types.Add (name, t);
+               } catch {
+                       HandleDuplicate (name, t);
+               }
+               builder_to_declspace.Add (t, en);
+       }
+
+       public static void AddMethod (MethodBase builder, IMethodData method)
+       {
+               builder_to_method.Add (builder, method);
+       }
+
+       public static IMethodData GetMethod (MethodBase builder)
+       {
+               return (IMethodData) builder_to_method [builder];
+       }
+
+       /// <summary>
+       ///   Returns the DeclSpace whose Type is `t' or null if there is no
+       ///   DeclSpace for `t' (ie, the Type comes from a library)
+       /// </summary>
+       public static DeclSpace LookupDeclSpace (Type t)
+       {
+               return builder_to_declspace [t] as DeclSpace;
+       }
+
+       /// <summary>
+       ///   Returns the TypeContainer whose Type is `t' or null if there is no
+       ///   TypeContainer for `t' (ie, the Type comes from a library)
+       /// </summary>
+       public static TypeContainer LookupTypeContainer (Type t)
+       {
+               return builder_to_declspace [t] as TypeContainer;
+       }
+
+       public static MemberCache LookupMemberCache (Type t)
+       {
+               if (t is TypeBuilder) {
+                       IMemberContainer container = builder_to_declspace [t] as IMemberContainer;
+                       if (container != null)
+                               return container.MemberCache;
+               }
+
+               if (t is GenericTypeParameterBuilder) {
+                       IMemberContainer container = builder_to_type_param [t] as IMemberContainer;
+
+                       if (container != null)
+                               return container.MemberCache;
+               }
+
+               return TypeHandle.GetMemberCache (t);
+       }
+
+       public static MemberCache LookupParentInterfacesCache (Type t)
+       {
+               Type [] ifaces = t.GetInterfaces ();
+
+               if (ifaces != null && ifaces.Length == 1)
+                       return LookupMemberCache (ifaces [0]);
+
+               // TODO: the builder_to_member_cache should be indexed by 'ifaces', not 't'
+               MemberCache cache = builder_to_member_cache [t] as MemberCache;
+               if (cache != null)
+                       return cache;
+
+               cache = new MemberCache (ifaces);
+               builder_to_member_cache.Add (t, cache);
+               return cache;
+       }
+
+       public static TypeContainer LookupInterface (Type t)
+       {
+               TypeContainer tc = (TypeContainer) builder_to_declspace [t];
+               if ((tc == null) || (tc.Kind != Kind.Interface))
+                       return null;
+
+               return tc;
+       }
+
+       public static Delegate LookupDelegate (Type t)
+       {
+               return builder_to_declspace [t] as Delegate;
+       }
+
+       public static Enum LookupEnum (Type t)
+       {
+               return builder_to_declspace [t] as Enum;
+       }
+       
+       public static Class LookupClass (Type t)
+       {
+               return (Class) builder_to_declspace [t];
+       }
+       
+       /// <summary>
+       ///   Registers an assembly to load types from.
+       /// </summary>
+       public static void AddAssembly (Assembly a)
+       {
+               foreach (Assembly assembly in assemblies) {
+                       if (a == assembly)
+                               return;
+               }
+
+               int top = assemblies.Length;
+               Assembly [] n = new Assembly [top + 1];
+
+               assemblies.CopyTo (n, 0);
+               
+               n [top] = a;
+               assemblies = n;
+       }
+
+        public static Assembly [] GetAssemblies ()
+        {
+                return assemblies;
+        }
+
+       /// <summary>
+       ///  Registers a module builder to lookup types from
+       /// </summary>
+       public static void AddModule (Module mb)
+       {
+               int top = modules != null ? modules.Length : 0;
+               Module [] n = new Module [top + 1];
+
+               if (modules != null)
+                       modules.CopyTo (n, 0);
+               n [top] = mb;
+               modules = n;
+       }
+
+       public static Module[] Modules {
+               get {
+                       return modules;
+               }
+       }
+
+       static Hashtable references = new Hashtable ();
+       
+       //
+       // Gets the reference to T version of the Type (T&)
+       //
+       public static Type GetReferenceType (Type t)
+       {
+               return t.MakeByRefType ();
+       }
+
+       static Hashtable pointers = new Hashtable ();
+
+       //
+       // Gets the pointer to T version of the Type  (T*)
+       //
+       public static Type GetPointerType (Type t)
+       {
+               string tname = t.FullName + "*";
+               
+               Type ret = t.Assembly.GetType (tname);
+               
+               //
+               // If the type comes from the assembly we are building
+               // We need the Hashtable, because .NET 1.1 will return different instance types
+               // every time we call ModuleBuilder.GetType.
+               //
+               if (ret == null){
+                       if (pointers [t] == null)
+                               pointers [t] = CodeGen.Module.Builder.GetType (tname);
+                       
+                       ret = (Type) pointers [t];
+               }
+
+               return ret;
+       }
+       
+       //
+       // Low-level lookup, cache-less
+       //
+       static Type LookupTypeReflection (string name)
+       {
+               Type t;
+
+               foreach (Assembly a in assemblies){
+                       t = a.GetType (name);
+                       if (t == null)
+                               continue;
+
+                       do {
+                               TypeAttributes ta = t.Attributes & TypeAttributes.VisibilityMask;
+                               if (ta == TypeAttributes.NotPublic ||
+                                   ta == TypeAttributes.NestedPrivate ||
+                                   ta == TypeAttributes.NestedAssembly ||
+                                   ta == TypeAttributes.NestedFamANDAssem){
+                                       
+                                       //
+                                       // In .NET pointers turn out to be private, even if their
+                                       // element type is not
+                                       //
+                                       if (t.IsPointer){
+                                               t = t.GetElementType ();
+                                               continue;
+                                       } else
+                                               t = null;
+                               } else {
+                                       return t;
+                               }
+                       } while (t != null);
+               }
+
+               foreach (Module mb in modules) {
+                       t = mb.GetType (name);
+                       if (t != null) 
+                               return t;
+               }
+                        
+               return null;
+       }
+
+       static Hashtable negative_hits = new Hashtable ();
+       
+       //
+       // This function is used when you want to avoid the lookups, and want to go
+       // directly to the source.  This will use the cache.
+       //
+       // Notice that bypassing the cache is bad, because on Microsoft.NET runtime
+       // GetType ("DynamicType[]") != GetType ("DynamicType[]"), and there is no
+       // way to test things other than doing a fullname compare
+       //
+       public static Type LookupTypeDirect (string name)
+       {
+               Type t = (Type) types [name];
+               if (t != null)
+                       return t;
+
+               t = LookupTypeReflection (name);
+               if (t == null)
+                       return null;
+
+               types [name] = t;
+               return t;
+       }
+
+       static readonly char [] dot_array = { '.' };
+
+       /// <summary>
+       ///   Returns the Type associated with @name, takes care of the fact that
+       ///   reflection expects nested types to be separated from the main type
+       ///   with a "+" instead of a "."
+       /// </summary>
+       public static Type LookupType (string name)
+       {
+               Type t;
+
+               //
+               // First lookup in user defined and cached values
+               //
+
+               t = (Type) types [name];
+               if (t != null)
+                       return t;
+
+               // Two thirds of the failures are caught here.
+               if (negative_hits.Contains (name))
+                       return null;
+
+               // Sadly, split takes a param array, so this ends up allocating *EVERY TIME*
+               string [] elements = name.Split (dot_array);
+               int count = elements.Length;
+
+               for (int n = 1; n <= count; n++){
+                       string top_level_type = String.Join (".", elements, 0, n);
+
+                       // One third of the failures are caught here.
+                       if (negative_hits.Contains (top_level_type))
+                               continue;
+                       
+                       t = (Type) types [top_level_type];
+                       if (t == null){
+                               t = LookupTypeReflection (top_level_type);
+                               if (t == null){
+                                       negative_hits [top_level_type] = null;
+                                       continue;
+                               }
+                       }
+                       
+                       if (count == n){
+                               types [name] = t;
+                               return t;
+                       } 
+
+                       //
+                       // We know that System.Object does not have children, and since its the parent of 
+                       // all the objects, it always gets probbed for inner classes. 
+                       //
+                       if (top_level_type == "System.Object")
+                               return null;
+                       
+                       string newt = top_level_type + "+" + String.Join ("+", elements, n, count - n);
+                       //Console.WriteLine ("Looking up: " + newt + " " + name);
+                       t = LookupTypeReflection (newt);
+                       if (t == null)
+                               negative_hits [name] = null;
+                       else
+                               types [name] = t;
+                       return t;
+               }
+               negative_hits [name] = null;
+               return null;
+       }
+
+       /// <summary>
+       ///   Computes the namespaces that we import from the assemblies we reference.
+       /// </summary>
+       public static void ComputeNamespaces ()
+       {
+               MethodInfo assembly_get_namespaces = typeof (Assembly).GetMethod ("GetNamespaces", BindingFlags.Instance|BindingFlags.NonPublic);
+
+               //
+               // First add the assembly namespaces
+               //
+               if (assembly_get_namespaces != null){
+                       int count = assemblies.Length;
+
+                       for (int i = 0; i < count; i++){
+                               Assembly a = assemblies [i];
+                               string [] namespaces = (string []) assembly_get_namespaces.Invoke (a, null);
+                               foreach (string ns in namespaces){
+                                       if (ns == "")
+                                               continue;
+                                       Namespace.LookupNamespace (ns, true);
+                               }
+                       }
+               } else {
+                       Hashtable cache = new Hashtable ();
+                       cache.Add ("", null);
+                       foreach (Assembly a in assemblies) {
+                               foreach (Type t in a.GetExportedTypes ()) {
+                                       string ns = t.Namespace;
+                                       if (ns == null || cache.Contains (ns))
+                                               continue;
+
+                                       Namespace.LookupNamespace (ns, true);
+                                       cache.Add (ns, null);
+                               }
+                       }
+               }
+       }
+
+       /// <summary>
+       /// Fills static table with exported types from all referenced assemblies.
+       /// This information is required for CLS Compliance tests.
+       /// </summary>
+       public static void LoadAllImportedTypes ()
+       {
+               all_imported_types = new Hashtable ();
+               foreach (Assembly a in assemblies) {
+                       foreach (Type t in a.GetExportedTypes ()) {
+                               all_imported_types [t.FullName] = t;
+                       }
+               }
+       }
+
+       public static bool NamespaceClash (string name, Location loc)
+       {
+               if (Namespace.LookupNamespace (name, false) == null)
+                       return false;
+
+               Report.Error (519, loc, String.Format ("`{0}' clashes with a predefined namespace", name));
+               return true;
+       }
+
+       /// <summary>
+       ///   Returns the C# name of a type if possible, or the full type name otherwise
+       /// </summary>
+       static public string CSharpName (Type t)
+       {
+               if (t.FullName == null)
+                       return t.Name;
+
+               return Regex.Replace (t.FullName, 
+                       @"^System\." +
+                       @"(Int32|UInt32|Int16|UInt16|Int64|UInt64|" +
+                       @"Single|Double|Char|Decimal|Byte|SByte|Object|" +
+                       @"Boolean|String|Void|Null)" +
+                       @"(\W+|\b)", 
+                       new MatchEvaluator (CSharpNameMatch));
+       }       
+       
+       static String CSharpNameMatch (Match match) 
+       {
+               string s = match.Groups [1].Captures [0].Value;
+               return s.ToLower ().
+               Replace ("int32", "int").
+               Replace ("uint32", "uint").
+               Replace ("int16", "short").
+               Replace ("uint16", "ushort").
+               Replace ("int64", "long").
+               Replace ("uint64", "ulong").
+               Replace ("single", "float").
+               Replace ("boolean", "bool")
+               + match.Groups [2].Captures [0].Value;
+       }
+
+        /// <summary>
+       ///  Returns the signature of the method with full namespace classification
+       /// </summary>
+       static public string GetFullNameSignature (MemberInfo mi)
+       {
+               return mi.DeclaringType.FullName.Replace ('+', '.') + '.' + mi.Name;
+       }
+               
+       static public string GetFullNameSignature (MethodBase mb)
+       {
+               string name = mb.Name;
+               if (name == ".ctor")
+                       name = mb.DeclaringType.Name;
+
+               if (mb.IsSpecialName) {
+                       if (name.StartsWith ("get_") || name.StartsWith ("set_")) {
+                               name = name.Remove (0, 4);
+                       }
+
+                       if (name == "Item")
+                               name = "this";
+               }
+
+               return mb.DeclaringType.FullName.Replace ('+', '.') + '.' + name;
+       }
+
+       static public string GetFullName (Type t)
+       {
+               if (t.FullName == null)
+                       return t.Name;
+
+               string name = t.FullName.Replace ('+', '.');
+
+               DeclSpace tc = LookupDeclSpace (t);
+               if ((tc != null) && tc.IsGeneric) {
+                       TypeParameter[] tparam = tc.TypeParameters;
+
+                       StringBuilder sb = new StringBuilder (name);
+                       sb.Append ("<");
+                       for (int i = 0; i < tparam.Length; i++) {
+                               if (i > 0)
+                                       sb.Append (",");
+                               sb.Append (tparam [i].Name);
+                       }
+                       sb.Append (">");
+                       return sb.ToString ();
+               } else if (t.HasGenericArguments && !t.IsGenericInstance) {
+                       Type[] tparam = t.GetGenericArguments ();
+
+                       StringBuilder sb = new StringBuilder (name);
+                       sb.Append ("<");
+                       for (int i = 0; i < tparam.Length; i++) {
+                               if (i > 0)
+                                       sb.Append (",");
+                               sb.Append (tparam [i].Name);
+                       }
+                       sb.Append (">");
+                       return sb.ToString ();
+               }
+
+               return name;
+       }
+
+       /// <summary>
+       ///   Returns the signature of the property and indexer
+       /// </summary>
+       static public string CSharpSignature (PropertyBuilder pb, bool is_indexer) 
+       {
+               if (!is_indexer) {
+                       return GetFullNameSignature (pb);
+               }
+
+               MethodBase mb = pb.GetSetMethod (true) != null ? pb.GetSetMethod (true) : pb.GetGetMethod (true);
+               string signature = GetFullNameSignature (mb);
+               string arg = TypeManager.LookupParametersByBuilder (mb).ParameterDesc (0);
+               return String.Format ("{0}.this[{1}]", signature.Substring (0, signature.LastIndexOf ('.')), arg);
+       }
+
+        /// <summary>
+        ///   Returns the signature of the method
+        /// </summary>
+        static public string CSharpSignature (MethodBase mb)
+        {
+               StringBuilder sig = new StringBuilder ("(");
+
+               //
+               // FIXME: We should really have a single function to do
+               // everything instead of the following 5 line pattern
+               //
+                ParameterData iparams = LookupParametersByBuilder (mb);
+
+               if (iparams == null)
+                       iparams = new ReflectionParameters (mb);
+               
+               // Is property
+               if (mb.IsSpecialName && iparams.Count == 0 && !mb.IsConstructor)
+                       return GetFullNameSignature (mb);
+               
+                for (int i = 0; i < iparams.Count; i++) {
+                        if (i > 0) {
+                               sig.Append (", ");
+                        }
+                       sig.Append (iparams.ParameterDesc (i));
+                }
+               sig.Append (")");
+
+               // Is indexer
+               if (mb.IsSpecialName && iparams.Count == 1 && !mb.IsConstructor) {
+                       sig.Replace ('(', '[');
+                       sig.Replace (')', ']');
+               }
+
+               return GetFullNameSignature (mb) + sig.ToString ();
+        }
+
+       public static string GetMethodName (MethodInfo m)
+       {
+               if (!IsGenericMethod (m))
+                       return m.Name;
+
+               return MemberName.MakeName (m.Name, m.GetGenericArguments ().Length);
+       }
+
+       /// <summary>
+       ///   Looks up a type, and aborts if it is not found.  This is used
+       ///   by types required by the compiler
+       /// </summary>
+       static Type CoreLookupType (string name)
+       {
+               Type t = LookupTypeDirect (name);
+
+               if (t == null){
+                       Report.Error (518, "The predefined type `" + name + "' is not defined or imported");
+                       Environment.Exit (1);
+               }
+
+               return t;
+       }
+
+       /// <summary>
+       ///   Returns the MethodInfo for a method named `name' defined
+       ///   in type `t' which takes arguments of types `args'
+       /// </summary>
+       static MethodInfo GetMethod (Type t, string name, Type [] args, bool is_private, bool report_errors)
+       {
+               MemberList list;
+               Signature sig;
+               BindingFlags flags = instance_and_static | BindingFlags.Public;
+
+               sig.name = name;
+               sig.args = args;
+               
+               if (is_private)
+                       flags |= BindingFlags.NonPublic;
+
+               list = FindMembers (t, MemberTypes.Method, flags, signature_filter, sig);
+               if (list.Count == 0) {
+                       if (report_errors)
+                               Report.Error (-19, "Can not find the core function `" + name + "'");
+                       return null;
+               }
+
+               MethodInfo mi = list [0] as MethodInfo;
+               if (mi == null) {
+                       if (report_errors)
+                               Report.Error (-19, "Can not find the core function `" + name + "'");
+                       return null;
+               }
+
+               return mi;
+       }
+
+       static MethodInfo GetMethod (Type t, string name, Type [] args, bool report_errors)
+       {
+               return GetMethod (t, name, args, false, report_errors);
+       }
+
+       static MethodInfo GetMethod (Type t, string name, Type [] args)
+       {
+               return GetMethod (t, name, args, true);
+       }
+
+
+       /// <summary>
+       ///    Returns the ConstructorInfo for "args"
+       /// </summary>
+       static ConstructorInfo GetConstructor (Type t, Type [] args)
+       {
+               MemberList list;
+               Signature sig;
+
+               sig.name = ".ctor";
+               sig.args = args;
+               
+               list = FindMembers (t, MemberTypes.Constructor,
+                                   instance_and_static | BindingFlags.Public | BindingFlags.DeclaredOnly,
+                                   signature_filter, sig);
+               if (list.Count == 0){
+                       Report.Error (-19, "Can not find the core constructor for type `" + t.Name + "'");
+                       return null;
+               }
+
+               ConstructorInfo ci = list [0] as ConstructorInfo;
+               if (ci == null){
+                       Report.Error (-19, "Can not find the core constructor for type `" + t.Name + "'");
+                       return null;
+               }
+
+               return ci;
+       }
+
+       public static void InitEnumUnderlyingTypes ()
+       {
+
+               int32_type    = CoreLookupType ("System.Int32");
+               int64_type    = CoreLookupType ("System.Int64");
+               uint32_type   = CoreLookupType ("System.UInt32"); 
+               uint64_type   = CoreLookupType ("System.UInt64"); 
+               byte_type     = CoreLookupType ("System.Byte");
+               sbyte_type    = CoreLookupType ("System.SByte");
+               short_type    = CoreLookupType ("System.Int16");
+               ushort_type   = CoreLookupType ("System.UInt16");
+       }
+       
+       /// <remarks>
+       ///   The types have to be initialized after the initial
+       ///   population of the type has happened (for example, to
+       ///   bootstrap the corlib.dll
+       /// </remarks>
+       public static void InitCoreTypes ()
+       {
+               object_type   = CoreLookupType ("System.Object");
+               value_type    = CoreLookupType ("System.ValueType");
+
+               InitEnumUnderlyingTypes ();
+
+               char_type     = CoreLookupType ("System.Char");
+               string_type   = CoreLookupType ("System.String");
+               float_type    = CoreLookupType ("System.Single");
+               double_type   = CoreLookupType ("System.Double");
+               char_ptr_type = CoreLookupType ("System.Char*");
+               decimal_type  = CoreLookupType ("System.Decimal");
+               bool_type     = CoreLookupType ("System.Boolean");
+               enum_type     = CoreLookupType ("System.Enum");
+
+               multicast_delegate_type = CoreLookupType ("System.MulticastDelegate");
+               delegate_type           = CoreLookupType ("System.Delegate");
+
+               array_type    = CoreLookupType ("System.Array");
+               void_type     = CoreLookupType ("System.Void");
+               type_type     = CoreLookupType ("System.Type");
+
+               runtime_field_handle_type = CoreLookupType ("System.RuntimeFieldHandle");
+               runtime_argument_handle_type = CoreLookupType ("System.RuntimeArgumentHandle");
+               runtime_helpers_type = CoreLookupType ("System.Runtime.CompilerServices.RuntimeHelpers");
+               default_member_type  = CoreLookupType ("System.Reflection.DefaultMemberAttribute");
+               runtime_handle_type  = CoreLookupType ("System.RuntimeTypeHandle");
+               asynccallback_type   = CoreLookupType ("System.AsyncCallback");
+               iasyncresult_type    = CoreLookupType ("System.IAsyncResult");
+               ienumerator_type     = CoreLookupType ("System.Collections.IEnumerator");
+               ienumerable_type     = CoreLookupType ("System.Collections.IEnumerable");
+               idisposable_type     = CoreLookupType ("System.IDisposable");
+               icloneable_type      = CoreLookupType ("System.ICloneable");
+               iconvertible_type    = CoreLookupType ("System.IConvertible");
+               monitor_type         = CoreLookupType ("System.Threading.Monitor");
+               intptr_type          = CoreLookupType ("System.IntPtr");
+
+               attribute_type       = CoreLookupType ("System.Attribute");
+               attribute_usage_type = CoreLookupType ("System.AttributeUsageAttribute");
+               dllimport_type       = CoreLookupType ("System.Runtime.InteropServices.DllImportAttribute");
+               methodimpl_attr_type = CoreLookupType ("System.Runtime.CompilerServices.MethodImplAttribute");
+               marshal_as_attr_type = CoreLookupType ("System.Runtime.InteropServices.MarshalAsAttribute");
+               param_array_type     = CoreLookupType ("System.ParamArrayAttribute");
+               in_attribute_type    = CoreLookupType ("System.Runtime.InteropServices.InAttribute");
+               typed_reference_type = CoreLookupType ("System.TypedReference");
+               arg_iterator_type    = CoreLookupType ("System.ArgIterator");
+               mbr_type             = CoreLookupType ("System.MarshalByRefObject");
+               decimal_constant_attribute_type = CoreLookupType ("System.Runtime.CompilerServices.DecimalConstantAttribute");
+
+               //
+               // Sigh. Remove this before the release.  Wonder what versions of Mono
+               // people are running.
+               //
+               guid_attr_type        = LookupType ("System.Runtime.InteropServices.GuidAttribute");
+
+               unverifiable_code_type= CoreLookupType ("System.Security.UnverifiableCodeAttribute");
+
+               void_ptr_type         = CoreLookupType ("System.Void*");
+
+               indexer_name_type     = CoreLookupType ("System.Runtime.CompilerServices.IndexerNameAttribute");
+
+               exception_type        = CoreLookupType ("System.Exception");
+               invalid_operation_exception_type = CoreLookupType ("System.InvalidOperationException");
+               not_supported_exception_type = CoreLookupType ("System.NotSupportedException");
+
+               //
+               // Attribute types
+               //
+               obsolete_attribute_type = CoreLookupType ("System.ObsoleteAttribute");
+               conditional_attribute_type = CoreLookupType ("System.Diagnostics.ConditionalAttribute");
+               cls_compliant_attribute_type = CoreLookupType ("System.CLSCompliantAttribute");
+               struct_layout_attribute_type = CoreLookupType ("System.Runtime.InteropServices.StructLayoutAttribute");
+               field_offset_attribute_type = CoreLookupType ("System.Runtime.InteropServices.FieldOffsetAttribute");
+               security_attr_type = CoreLookupType ("System.Security.Permissions.SecurityAttribute");
+
+               InitGenericCoreTypes ();
+
+               //
+               // When compiling corlib, store the "real" types here.
+               //
+               if (!RootContext.StdLib) {
+                       system_int32_type = typeof (System.Int32);
+                       system_array_type = typeof (System.Array);
+                       system_type_type = typeof (System.Type);
+                       system_assemblybuilder_type = typeof (System.Reflection.Emit.AssemblyBuilder);
+
+                       Type [] void_arg = {  };
+                       system_int_array_get_length = GetMethod (
+                               system_array_type, "get_Length", void_arg);
+                       system_int_array_get_rank = GetMethod (
+                               system_array_type, "get_Rank", void_arg);
+                       system_object_array_clone = GetMethod (
+                               system_array_type, "Clone", void_arg);
+
+                       Type [] system_int_arg = { system_int32_type };
+                       system_int_array_get_length_int = GetMethod (
+                               system_array_type, "GetLength", system_int_arg);
+                       system_int_array_get_upper_bound_int = GetMethod (
+                               system_array_type, "GetUpperBound", system_int_arg);
+                       system_int_array_get_lower_bound_int = GetMethod (
+                               system_array_type, "GetLowerBound", system_int_arg);
+
+                       Type [] system_array_int_arg = { system_array_type, system_int32_type };
+                       system_void_array_copyto_array_int = GetMethod (
+                               system_array_type, "CopyTo", system_array_int_arg);
+
+                       Type [] system_3_type_arg = {
+                               system_type_type, system_type_type, system_type_type };
+                       Type [] system_4_type_arg = {
+                               system_type_type, system_type_type, system_type_type, system_type_type };
+
+                       MethodInfo set_corlib_type_builders = GetMethod (
+                               system_assemblybuilder_type, "SetCorlibTypeBuilders",
+                               system_4_type_arg, true, false);
+
+                       if (set_corlib_type_builders != null) {
+                               object[] args = new object [4];
+                               args [0] = object_type;
+                               args [1] = value_type;
+                               args [2] = enum_type;
+                               args [3] = void_type;
+                               
+                               set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
+                       } else {
+                               // Compatibility for an older version of the class libs.
+                               set_corlib_type_builders = GetMethod (
+                                       system_assemblybuilder_type, "SetCorlibTypeBuilders",
+                                       system_3_type_arg, true, true);
+
+                               if (set_corlib_type_builders == null) {
+                                       Report.Error (-26, "Corlib compilation is not supported in Microsoft.NET due to bugs in it");
+                                       return;
+                               }
+
+                               object[] args = new object [3];
+                               args [0] = object_type;
+                               args [1] = value_type;
+                               args [2] = enum_type;
+                               
+                               set_corlib_type_builders.Invoke (CodeGen.Assembly.Builder, args);
+                       }
+               }
+
+               system_object_expr.Type = object_type;
+               system_string_expr.Type = string_type;
+               system_boolean_expr.Type = bool_type;
+               system_decimal_expr.Type = decimal_type;
+               system_single_expr.Type = float_type;
+               system_double_expr.Type = double_type;
+               system_sbyte_expr.Type = sbyte_type;
+               system_byte_expr.Type = byte_type;
+               system_int16_expr.Type = short_type;
+               system_uint16_expr.Type = ushort_type;
+               system_int32_expr.Type = int32_type;
+               system_uint32_expr.Type = uint32_type;
+               system_int64_expr.Type = int64_type;
+               system_uint64_expr.Type = uint64_type;
+               system_char_expr.Type = char_type;
+               system_void_expr.Type = void_type;
+               system_asynccallback_expr.Type = asynccallback_type;
+               system_iasyncresult_expr.Type = iasyncresult_type;
+               system_valuetype_expr.Type = value_type;
+
+               //
+               // These are only used for compare purposes
+               //
+               anonymous_method_type = typeof (AnonymousMethod);
+               null_type = typeof (NullType);
+       }
+
+       //
+       // The helper methods that are used by the compiler
+       //
+       public static void InitCodeHelpers ()
+       {
+               //
+               // Now load the default methods that we use.
+               //
+               Type [] string_string = { string_type, string_type };
+               string_concat_string_string = GetMethod (
+                       string_type, "Concat", string_string);
+               Type [] string_string_string = { string_type, string_type, string_type };
+               string_concat_string_string_string = GetMethod (
+                       string_type, "Concat", string_string_string);
+               Type [] string_string_string_string = { string_type, string_type, string_type, string_type };
+               string_concat_string_string_string_string = GetMethod (
+                       string_type, "Concat", string_string_string_string);
+               Type[] params_string = { TypeManager.LookupType ("System.String[]") };
+               string_concat_string_dot_dot_dot = GetMethod (
+                       string_type, "Concat", params_string);
+
+               Type [] object_object = { object_type, object_type };
+               string_concat_object_object = GetMethod (
+                       string_type, "Concat", object_object);
+               Type [] object_object_object = { object_type, object_type, object_type };
+               string_concat_object_object_object = GetMethod (
+                       string_type, "Concat", object_object_object);
+               Type[] params_object = { TypeManager.LookupType ("System.Object[]") };
+               string_concat_object_dot_dot_dot = GetMethod (
+                       string_type, "Concat", params_object);
+
+               Type [] string_ = { string_type };
+               string_isinterneted_string = GetMethod (
+                       string_type, "IsInterned", string_);
+               
+               Type [] runtime_type_handle = { runtime_handle_type };
+               system_type_get_type_from_handle = GetMethod (
+                       type_type, "GetTypeFromHandle", runtime_type_handle);
+
+               Type [] delegate_delegate = { delegate_type, delegate_type };
+               delegate_combine_delegate_delegate = GetMethod (
+                               delegate_type, "Combine", delegate_delegate);
+
+               delegate_remove_delegate_delegate = GetMethod (
+                               delegate_type, "Remove", delegate_delegate);
+
+               //
+               // Void arguments
+               //
+               Type [] void_arg = {  };
+               object_getcurrent_void = GetMethod (
+                       ienumerator_type, "get_Current", void_arg);
+               bool_movenext_void = GetMethod (
+                       ienumerator_type, "MoveNext", void_arg);
+               void_reset_void = GetMethod (
+                       ienumerator_type, "Reset", void_arg);
+               void_dispose_void = GetMethod (
+                       idisposable_type, "Dispose", void_arg);
+               int_get_offset_to_string_data = GetMethod (
+                       runtime_helpers_type, "get_OffsetToStringData", void_arg);
+               int_array_get_length = GetMethod (
+                       array_type, "get_Length", void_arg);
+               int_array_get_rank = GetMethod (
+                       array_type, "get_Rank", void_arg);
+               ienumerable_getenumerator_void = GetMethod (
+                       ienumerable_type, "GetEnumerator", void_arg);
+               
+               //
+               // Int32 arguments
+               //
+               Type [] int_arg = { int32_type };
+               int_array_get_length_int = GetMethod (
+                       array_type, "GetLength", int_arg);
+               int_array_get_upper_bound_int = GetMethod (
+                       array_type, "GetUpperBound", int_arg);
+               int_array_get_lower_bound_int = GetMethod (
+                       array_type, "GetLowerBound", int_arg);
+
+               //
+               // System.Array methods
+               //
+               object_array_clone = GetMethod (
+                       array_type, "Clone", void_arg);
+               Type [] array_int_arg = { array_type, int32_type };
+               void_array_copyto_array_int = GetMethod (
+                       array_type, "CopyTo", array_int_arg);
+               
+               //
+               // object arguments
+               //
+               Type [] object_arg = { object_type };
+               void_monitor_enter_object = GetMethod (
+                       monitor_type, "Enter", object_arg);
+               void_monitor_exit_object = GetMethod (
+                       monitor_type, "Exit", object_arg);
+
+               Type [] array_field_handle_arg = { array_type, runtime_field_handle_type };
+               
+               void_initializearray_array_fieldhandle = GetMethod (
+                       runtime_helpers_type, "InitializeArray", array_field_handle_arg);
+
+               //
+               // Array functions
+               //
+               int_getlength_int = GetMethod (
+                       array_type, "GetLength", int_arg);
+
+               //
+               // Decimal constructors
+               //
+               Type [] dec_arg = { int32_type, int32_type, int32_type, bool_type, byte_type };
+               void_decimal_ctor_five_args = GetConstructor (
+                       decimal_type, dec_arg);
+               
+               void_decimal_ctor_int_arg = GetConstructor (decimal_type, int_arg);
+
+               //
+               // Attributes
+               //
+               cons_param_array_attribute = GetConstructor (
+                       param_array_type, void_arg);
+
+               unverifiable_code_ctor = GetConstructor (
+                       unverifiable_code_type, void_arg);
+
+               decimal_constant_attribute_ctor = GetConstructor (decimal_constant_attribute_type, new Type []
+                       { byte_type, byte_type, uint32_type, uint32_type, uint32_type } );
+
+               default_member_ctor = GetConstructor (default_member_type, string_);
+
+               //
+               // InvalidOperationException
+               //
+               invalid_operation_ctor = GetConstructor (
+                       invalid_operation_exception_type, void_arg);
+
+
+               // Object
+               object_ctor = GetConstructor (object_type, void_arg);
+
+               InitGenericCodeHelpers ();
+       }
+
+       const BindingFlags instance_and_static = BindingFlags.Static | BindingFlags.Instance;
+
+       /// <remarks>
+       ///   This is the "old", non-cache based FindMembers() function.  We cannot use
+       ///   the cache here because there is no member name argument.
+       /// </remarks>
+       public static MemberList FindMembers (Type t, MemberTypes mt, BindingFlags bf,
+                                             MemberFilter filter, object criteria)
+       {
+               DeclSpace decl = (DeclSpace) builder_to_declspace [t];
+
+               //
+               // `builder_to_declspace' contains all dynamic types.
+               //
+               if (decl != null) {
+                       MemberList list;
+                       Timer.StartTimer (TimerType.FindMembers);
+                       list = decl.FindMembers (mt, bf, filter, criteria);
+                       Timer.StopTimer (TimerType.FindMembers);
+                       return list;
+               }
+
+               //
+               // We have to take care of arrays specially, because GetType on
+               // a TypeBuilder array will return a Type, not a TypeBuilder,
+               // and we can not call FindMembers on this type.
+               //
+               if (t.IsSubclassOf (TypeManager.array_type))
+                       return new MemberList (TypeManager.array_type.FindMembers (mt, bf, filter, criteria));
+
+               if (t is GenericTypeParameterBuilder) {
+                       TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
+
+                       Timer.StartTimer (TimerType.FindMembers);
+                       MemberList list = tparam.FindMembers (
+                               mt, bf | BindingFlags.DeclaredOnly, filter, criteria);
+                       Timer.StopTimer (TimerType.FindMembers);
+                       return list;
+               }
+
+               //
+               // Since FindMembers will not lookup both static and instance
+               // members, we emulate this behaviour here.
+               //
+               if ((bf & instance_and_static) == instance_and_static){
+                       MemberInfo [] i_members = t.FindMembers (
+                               mt, bf & ~BindingFlags.Static, filter, criteria);
+
+                       int i_len = i_members.Length;
+                       if (i_len == 1){
+                               MemberInfo one = i_members [0];
+
+                               //
+                               // If any of these are present, we are done!
+                               //
+                               if ((one is Type) || (one is EventInfo) || (one is FieldInfo))
+                                       return new MemberList (i_members);
+                       }
+                               
+                       MemberInfo [] s_members = t.FindMembers (
+                               mt, bf & ~BindingFlags.Instance, filter, criteria);
+
+                       int s_len = s_members.Length;
+                       if (i_len > 0 || s_len > 0)
+                               return new MemberList (i_members, s_members);
+                       else {
+                               if (i_len > 0)
+                                       return new MemberList (i_members);
+                               else
+                                       return new MemberList (s_members);
+                       }
+               }
+
+               return new MemberList (t.FindMembers (mt, bf, filter, criteria));
+       }
+
+
+       /// <summary>
+       ///   This method is only called from within MemberLookup.  It tries to use the member
+       ///   cache if possible and falls back to the normal FindMembers if not.  The `used_cache'
+       ///   flag tells the caller whether we used the cache or not.  If we used the cache, then
+       ///   our return value will already contain all inherited members and the caller don't need
+       ///   to check base classes and interfaces anymore.
+       /// </summary>
+       private static MemberInfo [] MemberLookup_FindMembers (Type t, MemberTypes mt, BindingFlags bf,
+                                                           string name, out bool used_cache)
+       {
+               MemberCache cache;
+
+               //
+               // We have to take care of arrays specially, because GetType on
+               // a TypeBuilder array will return a Type, not a TypeBuilder,
+               // and we can not call FindMembers on this type.
+               //
+               if (t == TypeManager.array_type || t.IsSubclassOf (TypeManager.array_type)) {
+                       used_cache = true;
+                       return TypeHandle.ArrayType.MemberCache.FindMembers (
+                               mt, bf, name, FilterWithClosure_delegate, null);
+               }
+
+               //
+               // If this is a dynamic type, it's always in the `builder_to_declspace' hash table
+               // and we can ask the DeclSpace for the MemberCache.
+               //
+               if (t is TypeBuilder) {
+                       DeclSpace decl = (DeclSpace) builder_to_declspace [t];
+                       cache = decl.MemberCache;
+
+                       //
+                       // If this DeclSpace has a MemberCache, use it.
+                       //
+
+                       if (cache != null) {
+                               used_cache = true;
+                               return cache.FindMembers (
+                                       mt, bf, name, FilterWithClosure_delegate, null);
+                       }
+
+                       // If there is no MemberCache, we need to use the "normal" FindMembers.
+                       // Note, this is a VERY uncommon route!
+
+                       MemberList list;
+                       Timer.StartTimer (TimerType.FindMembers);
+                       list = decl.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
+                                                FilterWithClosure_delegate, name);
+                       Timer.StopTimer (TimerType.FindMembers);
+                       used_cache = false;
+                       return (MemberInfo []) list;
+               }
+
+               if (t is GenericTypeParameterBuilder) {
+                       TypeParameter tparam = (TypeParameter) builder_to_type_param [t];
+
+                       MemberList list;
+                       Timer.StartTimer (TimerType.FindMembers);
+                       list = tparam.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
+                                                  FilterWithClosure_delegate, name);
+                       Timer.StopTimer (TimerType.FindMembers);
+                       used_cache = false;
+                       return (MemberInfo []) list;
+               }
+
+               //
+               // This call will always succeed.  There is exactly one TypeHandle instance per
+               // type, TypeHandle.GetMemberCache() will, if necessary, create a new one, and return
+               // the corresponding MemberCache.
+               //
+               cache = TypeHandle.GetMemberCache (t);
+
+               used_cache = true;
+               return cache.FindMembers (mt, bf, name, FilterWithClosure_delegate, null);
+       }
+
+       public static bool IsBuiltinType (Type t)
+       {
+               if (t == object_type || t == string_type || t == int32_type || t == uint32_type ||
+                   t == int64_type || t == uint64_type || t == float_type || t == double_type ||
+                   t == char_type || t == short_type || t == decimal_type || t == bool_type ||
+                   t == sbyte_type || t == byte_type || t == ushort_type || t == void_type)
+                       return true;
+               else
+                       return false;
+       }
+
+       public static bool IsBuiltinType (TypeContainer tc)
+       {
+               return IsBuiltinType (tc.TypeBuilder);
+       }
+
+       //
+       // This is like IsBuiltinType, but lacks decimal_type, we should also clean up
+       // the pieces in the code where we use IsBuiltinType and special case decimal_type.
+       // 
+       public static bool IsCLRType (Type t)
+       {
+               if (t == object_type || t == int32_type || t == uint32_type ||
+                   t == int64_type || t == uint64_type || t == float_type || t == double_type ||
+                   t == char_type || t == short_type || t == bool_type ||
+                   t == sbyte_type || t == byte_type || t == ushort_type)
+                       return true;
+               else
+                       return false;
+       }
+
+       public static bool IsDelegateType (Type t)
+       {
+               if (t.IsGenericInstance)
+                       t = t.GetGenericTypeDefinition ();
+
+               if (t.IsSubclassOf (TypeManager.delegate_type))
+                       return true;
+               else
+                       return false;
+       }
+       
+       public static bool IsEnumType (Type t)
+       {
+               if (t.IsSubclassOf (TypeManager.enum_type))
+                       return true;
+               else
+                       return false;
+       }
+       public static bool IsBuiltinOrEnum (Type t)
+       {
+               if (IsBuiltinType (t))
+                       return true;
+               
+               if (IsEnumType (t))
+                       return true;
+
+               return false;
+       }
+
+       public static bool IsNullType (Type t)
+       {
+               return t == null_type;
+       }
+       
+       //
+       // Whether a type is unmanaged.  This is used by the unsafe code (25.2)
+       //
+       public static bool IsUnmanagedType (Type t)
+       {
+               if (IsBuiltinType (t) && t != TypeManager.string_type)
+                       return true;
+
+               if (IsEnumType (t))
+                       return true;
+
+               if (t.IsPointer)
+                       return true;
+
+               if (IsValueType (t)){
+                       if (t is TypeBuilder){
+                               TypeContainer tc = LookupTypeContainer (t);
+
+                               if (tc.Fields != null){
+                               foreach (Field f in tc.Fields){
+                                       if (f.FieldBuilder.IsStatic)
+                                               continue;
+                                       if (!IsUnmanagedType (f.FieldBuilder.FieldType))
+                                               return false;
+                               }
+                               } else
+                                       return true;
+                       } else {
+                               FieldInfo [] fields = t.GetFields ();
+
+                               foreach (FieldInfo f in fields){
+                                       if (f.IsStatic)
+                                               continue;
+                                       if (!IsUnmanagedType (f.FieldType))
+                                               return false;
+                               }
+                       }
+                       return true;
+               }
+
+               return false;
+       }
+               
+       public static bool IsValueType (Type t)
+       {
+               return t.IsGenericParameter || t.IsValueType;
+       }
+       
+       public static bool IsInterfaceType (Type t)
+       {
+               TypeContainer tc = (TypeContainer) builder_to_declspace [t];
+               if (tc == null)
+                       return false;
+
+               return tc.Kind == Kind.Interface;
+       }
+
+       public static bool IsSubclassOf (Type type, Type parent)
+       {
+               TypeParameter tparam = LookupTypeParameter (type);
+               TypeParameter pparam = LookupTypeParameter (parent);
+
+               if ((tparam != null) && (pparam != null)) {
+                       if (tparam == pparam)
+                               return true;
+
+                       return tparam.IsSubclassOf (parent);
+               }
+
+               do {
+                       if (type.Equals (parent))
+                               return true;
+
+                       type = type.BaseType;
+               } while (type != null);
+
+               return false;
+       }
+
+       public static bool IsPrivateAccessible (Type type, Type parent)
+       {
+               if (type.Equals (parent))
+                       return true;
+
+               if ((type is TypeBuilder) && type.IsGenericTypeDefinition && parent.IsGenericInstance) {
+                       //
+                       // `a' is a generic type definition's TypeBuilder and `b' is a
+                       // generic instance of the same type.
+                       //
+                       // Example:
+                       //
+                       // class Stack<T>
+                       // {
+                       //     void Test (Stack<T> stack) { }
+                       // }
+                       //
+                       // The first argument of `Test' will be the generic instance
+                       // "Stack<!0>" - which is the same type than the "Stack" TypeBuilder.
+                       //
+                       //
+                       // We hit this via Closure.Filter() for gen-82.cs.
+                       //
+                       if (type != parent.GetGenericTypeDefinition ())
+                               return false;
+
+                       return true;
+               }
+
+               if (type.IsGenericInstance && parent.IsGenericInstance) {
+                       Type tdef = type.GetGenericTypeDefinition ();
+                       Type pdef = parent.GetGenericTypeDefinition ();
+
+                       if (type.GetGenericTypeDefinition () != parent.GetGenericTypeDefinition ())
+                               return false;
+
+                       return true;
+               }
+
+               return false;
+       }
+
+       public static bool IsFamilyAccessible (Type type, Type parent)
+       {
+               TypeParameter tparam = LookupTypeParameter (type);
+               TypeParameter pparam = LookupTypeParameter (parent);
+
+               if ((tparam != null) && (pparam != null)) {
+                       if (tparam == pparam)
+                               return true;
+
+                       return tparam.IsSubclassOf (parent);
+               }
+
+               do {
+                       if (IsEqualGenericInstance (type, parent))
+                               return true;
+
+                       type = type.BaseType;
+               } while (type != null);
+
+               return false;
+       }
+
+       //
+       // Checks whether `type' is a subclass or nested child of `parent'.
+       //
+       public static bool IsNestedFamilyAccessible (Type type, Type parent)
+       {
+               do {
+                       if (IsFamilyAccessible (type, parent))
+                               return true;
+
+                       // Handle nested types.
+                       type = type.DeclaringType;
+               } while (type != null);
+
+               return false;
+       }
+
+       //
+       // Checks whether `type' is a nested child of `parent'.
+       //
+       public static bool IsNestedChildOf (Type type, Type parent)
+       {
+               if (IsEqual (type, parent))
+                       return false;
+
+               type = type.DeclaringType;
+               while (type != null) {
+                       if (IsEqual (type, parent))
+                               return true;
+
+                       type = type.DeclaringType;
+               }
+
+               return false;
+       }
+
+        //
+        // Do the right thing when returning the element type of an
+        // array type based on whether we are compiling corlib or not
+        //
+        public static Type GetElementType (Type t)
+        {
+                if (RootContext.StdLib)
+                        return t.GetElementType ();
+                else
+                        return TypeToCoreType (t.GetElementType ());
+        }
+
+       /// <summary>
+       ///   Returns the User Defined Types
+       /// </summary>
+       public static ArrayList UserTypes {
+               get {
+                       return user_types;
+               }
+       }
+
+       public static Hashtable TypeContainers {
+               get {
+                       return typecontainers;
+               }
+       }
+
+       static Hashtable builder_to_constant;
+
+       public static void RegisterConstant (FieldBuilder fb, Const c)
+       {
+               if (builder_to_constant == null)
+                       builder_to_constant = new PtrHashtable ();
+
+               if (builder_to_constant.Contains (fb))
+                       return;
+
+               builder_to_constant.Add (fb, c);
+       }
+
+       public static Const LookupConstant (FieldBuilder fb)
+       {
+               if (builder_to_constant == null)
+                       return null;
+               
+               return (Const) builder_to_constant [fb];
+       }
+       
+       /// <summary>
+       ///   Gigantic work around for missing features in System.Reflection.Emit follows.
+       /// </summary>
+       ///
+       /// <remarks>
+       ///   Since System.Reflection.Emit can not return MethodBase.GetParameters
+       ///   for anything which is dynamic, and we need this in a number of places,
+       ///   we register this information here, and use it afterwards.
+       /// </remarks>
+       static public void RegisterMethod (MethodBase mb, InternalParameters ip, Type [] args)
+       {
+               if (args == null)
+                       args = NoTypes;
+                               
+               method_arguments.Add (mb, args);
+               method_internal_params.Add (mb, ip);
+       }
+       
+       static public InternalParameters LookupParametersByBuilder (MethodBase mb)
+       {
+               if (! (mb is ConstructorBuilder || mb is MethodBuilder))
+                       return null;
+               
+               if (method_internal_params.Contains (mb))
+                       return (InternalParameters) method_internal_params [mb];
+               else
+                       throw new Exception ("Argument for Method not registered" + mb);
+       }
+
+       /// <summary>
+       ///    Returns the argument types for a method based on its methodbase
+       ///
+       ///    For dynamic methods, we use the compiler provided types, for
+       ///    methods from existing assemblies we load them from GetParameters,
+       ///    and insert them into the cache
+       /// </summary>
+       static public Type [] GetArgumentTypes (MethodBase mb)
+       {
+               object t = method_arguments [mb];
+               if (t != null)
+                       return (Type []) t;
+
+                       ParameterInfo [] pi = mb.GetParameters ();
+                       int c = pi.Length;
+               Type [] types;
+                       
+               if (c == 0) {
+                       types = NoTypes;
+               } else {
+                       types = new Type [c];
+                       for (int i = 0; i < c; i++)
+                               types [i] = pi [i].ParameterType;
+               }
+                       method_arguments.Add (mb, types);
+                       return types;
+               }
+
+       /// <summary>
+       ///    Returns the argument types for an indexer based on its PropertyInfo
+       ///
+       ///    For dynamic indexers, we use the compiler provided types, for
+       ///    indexers from existing assemblies we load them from GetParameters,
+       ///    and insert them into the cache
+       /// </summary>
+       static public Type [] GetArgumentTypes (PropertyInfo indexer)
+       {
+               if (indexer_arguments.Contains (indexer))
+                       return (Type []) indexer_arguments [indexer];
+               else if (indexer is PropertyBuilder)
+                       // If we're a PropertyBuilder and not in the
+                       // `indexer_arguments' hash, then we're a property and
+                       // not an indexer.
+                       return NoTypes;
+               else {
+                       ParameterInfo [] pi = indexer.GetIndexParameters ();
+                       // Property, not an indexer.
+                       if (pi == null)
+                               return NoTypes;
+                       int c = pi.Length;
+                       Type [] types = new Type [c];
+                       
+                       for (int i = 0; i < c; i++)
+                               types [i] = pi [i].ParameterType;
+
+                       indexer_arguments.Add (indexer, types);
+                       return types;
+               }
+       }
+       
+       // <remarks>
+       //  This is a workaround the fact that GetValue is not
+       //  supported for dynamic types
+       // </remarks>
+       static Hashtable fields = new Hashtable ();
+       static public bool RegisterFieldValue (FieldBuilder fb, object value)
+       {
+               if (fields.Contains (fb))
+                       return false;
+
+               fields.Add (fb, value);
+
+               return true;
+       }
+
+       static public object GetValue (FieldBuilder fb)
+       {
+               return fields [fb];
+       }
+
+       static Hashtable fieldbuilders_to_fields = new Hashtable ();
+       static public bool RegisterFieldBase (FieldBuilder fb, FieldBase f)
+       {
+               if (fieldbuilders_to_fields.Contains (fb))
+                       return false;
+
+               fieldbuilders_to_fields.Add (fb, f);
+               return true;
+       }
+
+       //
+       // The return value can be null;  This will be the case for
+       // auxiliary FieldBuilders created by the compiler that have no
+       // real field being declared on the source code
+       //
+       static public FieldBase GetField (FieldInfo fb)
+       {
+               return (FieldBase) fieldbuilders_to_fields [fb];
+       }
+       
+       static Hashtable events;
+
+       static public void RegisterEvent (MyEventBuilder eb, MethodBase add, MethodBase remove)
+       {
+               if (events == null)
+                       events = new Hashtable ();
+
+               if (!events.Contains (eb)) {
+               events.Add (eb, new Pair (add, remove));
+               }
+       }
+
+       static public MethodInfo GetAddMethod (EventInfo ei)
+       {
+               if (ei is MyEventBuilder) {
+                       Pair pair = (Pair) events [ei];
+
+                       return (MethodInfo) pair.First;
+               }
+               return ei.GetAddMethod (true);
+       }
+
+       static public MethodInfo GetRemoveMethod (EventInfo ei)
+       {
+               if (ei is MyEventBuilder) {
+                       Pair pair = (Pair) events [ei];
+
+                       return (MethodInfo) pair.Second;
+               }
+               return ei.GetRemoveMethod (true);
+       }
+
+       static Hashtable priv_fields_events;
+
+       static public bool RegisterPrivateFieldOfEvent (EventInfo einfo, FieldBuilder builder)
+       {
+               if (priv_fields_events == null)
+                       priv_fields_events = new Hashtable ();
+
+               if (priv_fields_events.Contains (einfo))
+                       return false;
+
+               priv_fields_events.Add (einfo, builder);
+
+               return true;
+       }
+
+       static public MemberInfo GetPrivateFieldOfEvent (EventInfo ei)
+       {
+               if (priv_fields_events == null)
+                       return null;
+               else
+                       return (MemberInfo) priv_fields_events [ei];
+       }
+               
+       static Hashtable properties;
+       
+       static public bool RegisterProperty (PropertyBuilder pb, MethodBase get, MethodBase set)
+       {
+               if (properties == null)
+                       properties = new Hashtable ();
+
+               if (properties.Contains (pb))
+                       return false;
+
+               properties.Add (pb, new Pair (get, set));
+
+               return true;
+       }
+
+       static public bool RegisterIndexer (PropertyBuilder pb, MethodBase get,
+                                            MethodBase set, Type[] args)
+       {
+               if (!RegisterProperty (pb, get,set))
+                       return false;
+
+               indexer_arguments.Add (pb, args);
+
+               return true;
+       }
+
+       public static bool CheckStructCycles (TypeContainer tc, Hashtable seen)
+       {
+               Hashtable hash = new Hashtable ();
+               return CheckStructCycles (tc, seen, hash);
+       }
+
+       public static bool CheckStructCycles (TypeContainer tc, Hashtable seen,
+                                             Hashtable hash)
+       {
+               if ((tc.Kind != Kind.Struct) || IsBuiltinType (tc))
+                       return true;
+
+               //
+               // `seen' contains all types we've already visited.
+               //
+               if (seen.Contains (tc))
+                       return true;
+               seen.Add (tc, null);
+
+               if (tc.Fields == null)
+                       return true;
+
+               foreach (Field field in tc.Fields) {
+                       if (field.FieldBuilder.IsStatic)
+                               continue;
+
+                       Type ftype = field.FieldBuilder.FieldType;
+                       TypeContainer ftc = LookupTypeContainer (ftype);
+                       if (ftc == null)
+                               continue;
+
+                       if (hash.Contains (ftc)) {
+                               Report.Error (523, tc.Location,
+                                             "Struct member `{0}.{1}' of type `{2}' " +
+                                             "causes a cycle in the struct layout",
+                                             tc.Name, field.Name, ftc.Name);
+                               return false;
+                       }
+
+                       //
+                       // `hash' contains all types in the current path.
+                       //
+                       hash.Add (tc, null);
+
+                       bool ok = CheckStructCycles (ftc, seen, hash);
+
+                       hash.Remove (tc);
+
+                       if (!ok)
+                               return false;
+
+                       if (!seen.Contains (ftc))
+                               seen.Add (ftc, null);
+               }
+
+               return true;
+       }
+
+       /// <summary>
+       ///   Given an array of interface types, expand and eliminate repeated ocurrences
+       ///   of an interface.  
+       /// </summary>
+       ///
+       /// <remarks>
+       ///   This expands in context like: IA; IB : IA; IC : IA, IB; the interface "IC" to
+       ///   be IA, IB, IC.
+       /// </remarks>
+       public static Type[] ExpandInterfaces (EmitContext ec, TypeExpr [] base_interfaces)
+       {
+               ArrayList new_ifaces = new ArrayList ();
+
+               foreach (TypeExpr iface in base_interfaces){
+                       TypeExpr texpr = iface.ResolveAsTypeTerminal (ec);
+                       if (texpr == null)
+                               return null;
+
+                       if (!new_ifaces.Contains (texpr.Type))
+                               new_ifaces.Add (texpr.Type);
+                       
+                       Type [] implementing = texpr.Type.GetInterfaces ();
+                       
+                       foreach (Type imp in implementing){
+                               if (!new_ifaces.Contains (imp))
+                                       new_ifaces.Add (imp);
+                       }
+               }
+               Type [] ret = new Type [new_ifaces.Count];
+               new_ifaces.CopyTo (ret, 0);
+               return ret;
+       }
+               
+       static PtrHashtable iface_cache = new PtrHashtable ();
+               
+       /// <summary>
+       ///   This function returns the interfaces in the type `t'.  Works with
+       ///   both types and TypeBuilders.
+       /// </summary>
+       public static Type [] GetInterfaces (Type t)
+       {
+               
+               Type [] cached = iface_cache [t] as Type [];
+               if (cached != null)
+                       return cached;
+               
+               //
+               // The reason for catching the Array case is that Reflection.Emit
+               // will not return a TypeBuilder for Array types of TypeBuilder types,
+               // but will still throw an exception if we try to call GetInterfaces
+               // on the type.
+               //
+               // Since the array interfaces are always constant, we return those for
+               // the System.Array
+               //
+               
+               if (t.IsArray)
+                       t = TypeManager.array_type;
+               
+               if (t is TypeBuilder){
+                       Type[] parent_ifaces;
+                       
+                       if (t.BaseType == null)
+                               parent_ifaces = NoTypes;
+                       else
+                               parent_ifaces = GetInterfaces (t.BaseType);
+                       Type[] type_ifaces = (Type []) builder_to_ifaces [t];
+                       if (type_ifaces == null)
+                               type_ifaces = NoTypes;
+
+                       int parent_count = parent_ifaces.Length;
+                       Type[] result = new Type [parent_count + type_ifaces.Length];
+                       parent_ifaces.CopyTo (result, 0);
+                       type_ifaces.CopyTo (result, parent_count);
+
+                       iface_cache [t] = result;
+                       return result;
+               } else if (t is GenericTypeParameterBuilder){
+                       Type[] type_ifaces = (Type []) builder_to_ifaces [t];
+                       if (type_ifaces == null)
+                               type_ifaces = NoTypes;
+
+                       iface_cache [t] = type_ifaces;
+                       return type_ifaces;
+               } else {
+                       Type[] ifaces = t.GetInterfaces ();
+                       iface_cache [t] = ifaces;
+                       return ifaces;
+               }
+       }
+       
+       //
+       // gets the interfaces that are declared explicitly on t
+       //
+       public static Type [] GetExplicitInterfaces (TypeBuilder t)
+       {
+               return (Type []) builder_to_ifaces [t];
+       }
+       
+       /// <remarks>
+       ///  The following is used to check if a given type implements an interface.
+       ///  The cache helps us reduce the expense of hitting Type.GetInterfaces everytime.
+       /// </remarks>
+       public static bool ImplementsInterface (Type t, Type iface)
+       {
+               Type [] interfaces;
+
+               //
+               // FIXME OPTIMIZATION:
+               // as soon as we hit a non-TypeBuiler in the interface
+               // chain, we could return, as the `Type.GetInterfaces'
+               // will return all the interfaces implement by the type
+               // or its parents.
+               //
+               do {
+                       interfaces = GetInterfaces (t);
+
+                       if (interfaces != null){
+                               foreach (Type i in interfaces){
+                                       if (i == iface)
+                                               return true;
+                               }
+                       }
+                       
+                       t = t.BaseType;
+               } while (t != null);
+               
+               return false;
+       }
+
+       static NumberFormatInfo nf_provider = CultureInfo.CurrentCulture.NumberFormat;
+
+       // This is a custom version of Convert.ChangeType() which works
+       // with the TypeBuilder defined types when compiling corlib.
+       public static object ChangeType (object value, Type conversionType, out bool error)
+       {
+               IConvertible convert_value = value as IConvertible;
+               
+               if (convert_value == null){
+                       error = true;
+                       return null;
+               }
+               
+               //
+               // We must use Type.Equals() here since `conversionType' is
+               // the TypeBuilder created version of a system type and not
+               // the system type itself.  You cannot use Type.GetTypeCode()
+               // on such a type - it'd always return TypeCode.Object.
+               //
+               error = false;
+               try {
+                       if (conversionType.Equals (typeof (Boolean)))
+                               return (object)(convert_value.ToBoolean (nf_provider));
+                       else if (conversionType.Equals (typeof (Byte)))
+                               return (object)(convert_value.ToByte (nf_provider));
+                       else if (conversionType.Equals (typeof (Char)))
+                               return (object)(convert_value.ToChar (nf_provider));
+                       else if (conversionType.Equals (typeof (DateTime)))
+                               return (object)(convert_value.ToDateTime (nf_provider));
+                       else if (conversionType.Equals (TypeManager.decimal_type)) // typeof (Decimal)))
+                               return (object)(convert_value.ToDecimal (nf_provider));
+                       else if (conversionType.Equals (typeof (Double)))
+                               return (object)(convert_value.ToDouble (nf_provider));
+                       else if (conversionType.Equals (typeof (Int16)))
+                               return (object)(convert_value.ToInt16 (nf_provider));
+                       else if (conversionType.Equals (typeof (Int32)))
+                               return (object)(convert_value.ToInt32 (nf_provider));
+                       else if (conversionType.Equals (typeof (Int64)))
+                               return (object)(convert_value.ToInt64 (nf_provider));
+                       else if (conversionType.Equals (typeof (SByte)))
+                               return (object)(convert_value.ToSByte (nf_provider));
+                       else if (conversionType.Equals (typeof (Single)))
+                               return (object)(convert_value.ToSingle (nf_provider));
+                       else if (conversionType.Equals (typeof (String)))
+                               return (object)(convert_value.ToString (nf_provider));
+                       else if (conversionType.Equals (typeof (UInt16)))
+                               return (object)(convert_value.ToUInt16 (nf_provider));
+                       else if (conversionType.Equals (typeof (UInt32)))
+                               return (object)(convert_value.ToUInt32 (nf_provider));
+                       else if (conversionType.Equals (typeof (UInt64)))
+                               return (object)(convert_value.ToUInt64 (nf_provider));
+                       else if (conversionType.Equals (typeof (Object)))
+                               return (object)(value);
+                       else 
+                               error = true;
+               } catch {
+                       error = true;
+               }
+               return null;
+       }
+
+       //
+       // This is needed, because enumerations from assemblies
+       // do not report their underlyingtype, but they report
+       // themselves
+       //
+       public static Type EnumToUnderlying (Type t)
+       {
+               if (t == TypeManager.enum_type)
+                       return t;
+
+               t = t.UnderlyingSystemType;
+               if (!TypeManager.IsEnumType (t))
+                       return t;
+       
+               if (t is TypeBuilder) {
+                       // slow path needed to compile corlib
+                       if (t == TypeManager.bool_type ||
+                                       t == TypeManager.byte_type ||
+                                       t == TypeManager.sbyte_type ||
+                                       t == TypeManager.char_type ||
+                                       t == TypeManager.short_type ||
+                                       t == TypeManager.ushort_type ||
+                                       t == TypeManager.int32_type ||
+                                       t == TypeManager.uint32_type ||
+                                       t == TypeManager.int64_type ||
+                                       t == TypeManager.uint64_type)
+                               return t;
+                       throw new Exception ("Unhandled typecode in enum " + " from " + t.AssemblyQualifiedName);
+               }
+               TypeCode tc = Type.GetTypeCode (t);
+
+               switch (tc){
+               case TypeCode.Boolean:
+                       return TypeManager.bool_type;
+               case TypeCode.Byte:
+                       return TypeManager.byte_type;
+               case TypeCode.SByte:
+                       return TypeManager.sbyte_type;
+               case TypeCode.Char:
+                       return TypeManager.char_type;
+               case TypeCode.Int16:
+                       return TypeManager.short_type;
+               case TypeCode.UInt16:
+                       return TypeManager.ushort_type;
+               case TypeCode.Int32:
+                       return TypeManager.int32_type;
+               case TypeCode.UInt32:
+                       return TypeManager.uint32_type;
+               case TypeCode.Int64:
+                       return TypeManager.int64_type;
+               case TypeCode.UInt64:
+                       return TypeManager.uint64_type;
+               }
+               throw new Exception ("Unhandled typecode in enum " + tc + " from " + t.AssemblyQualifiedName);
+       }
+
+       //
+       // When compiling corlib and called with one of the core types, return
+       // the corresponding typebuilder for that type.
+       //
+       public static Type TypeToCoreType (Type t)
+       {
+               if (RootContext.StdLib || (t is TypeBuilder))
+                       return t;
+
+               TypeCode tc = Type.GetTypeCode (t);
+
+               switch (tc){
+               case TypeCode.Boolean:
+                       return TypeManager.bool_type;
+               case TypeCode.Byte:
+                       return TypeManager.byte_type;
+               case TypeCode.SByte:
+                       return TypeManager.sbyte_type;
+               case TypeCode.Char:
+                       return TypeManager.char_type;
+               case TypeCode.Int16:
+                       return TypeManager.short_type;
+               case TypeCode.UInt16:
+                       return TypeManager.ushort_type;
+               case TypeCode.Int32:
+                       return TypeManager.int32_type;
+               case TypeCode.UInt32:
+                       return TypeManager.uint32_type;
+               case TypeCode.Int64:
+                       return TypeManager.int64_type;
+               case TypeCode.UInt64:
+                       return TypeManager.uint64_type;
+               case TypeCode.Single:
+                       return TypeManager.float_type;
+               case TypeCode.Double:
+                       return TypeManager.double_type;
+               case TypeCode.String:
+                       return TypeManager.string_type;
+               case TypeCode.Decimal:
+                       return TypeManager.decimal_type;
+               default:
+                       if (t == typeof (void))
+                               return TypeManager.void_type;
+                       if (t == typeof (object))
+                               return TypeManager.object_type;
+                       if (t == typeof (System.Type))
+                               return TypeManager.type_type;
+                       if (t == typeof (System.IntPtr))
+                               return TypeManager.intptr_type;
+                       return t;
+               }
+       }
+
+       /// <summary>
+       ///   Utility function that can be used to probe whether a type
+       ///   is managed or not.  
+       /// </summary>
+       public static bool VerifyUnManaged (Type t, Location loc)
+       {
+               if (t.IsValueType || t.IsPointer){
+                       //
+                       // FIXME: this is more complex, we actually need to
+                       // make sure that the type does not contain any
+                       // classes itself
+                       //
+                       return true;
+               }
+
+               if (!RootContext.StdLib && (t == TypeManager.decimal_type))
+                       // We need this explicit check here to make it work when
+                       // compiling corlib.
+                       return true;
+
+               Report.Error (
+                       208, loc,
+                       "Cannot take the address or size of a variable of a managed type ('" +
+                       CSharpName (t) + "')");
+               return false;   
+       }
+       
+       /// <summary>
+       ///   Returns the name of the indexer in a given type.
+       /// </summary>
+       /// <remarks>
+       ///   The default is not always `Item'.  The user can change this behaviour by
+       ///   using the IndexerNameAttribute in the container.
+       ///
+       ///   For example, the String class indexer is named `Chars' not `Item' 
+       /// </remarks>
+       public static string IndexerPropertyName (Type t)
+       {
+               if (t.IsGenericInstance)
+                       t = t.GetGenericTypeDefinition ();
+
+               if (t is TypeBuilder) {
+                       TypeContainer tc = t.IsInterface ? LookupInterface (t) : LookupTypeContainer (t);
+                       return tc == null ? TypeContainer.DefaultIndexerName : tc.IndexerName;
+               }
+               
+               System.Attribute attr = System.Attribute.GetCustomAttribute (
+                       t, TypeManager.default_member_type);
+               if (attr != null){
+                       DefaultMemberAttribute dma = (DefaultMemberAttribute) attr;
+                       return dma.MemberName;
+               }
+
+               return TypeContainer.DefaultIndexerName;
+       }
+
+       static MethodInfo declare_local_method = null;
+       
+       public static LocalBuilder DeclareLocalPinned (ILGenerator ig, Type t)
+       {
+               if (declare_local_method == null){
+                       declare_local_method = typeof (ILGenerator).GetMethod (
+                               "DeclareLocal",
+                               BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
+                               null, 
+                               new Type [] { typeof (Type), typeof (bool)},
+                               null);
+                       if (declare_local_method == null){
+                               Report.Warning (-24, new Location (-1),
+                                               "This version of the runtime does not support making pinned local variables.  " +
+                                       "This code may cause errors on a runtime with a moving GC");
+                               return ig.DeclareLocal (t);
+                       }
+               }
+               return (LocalBuilder) declare_local_method.Invoke (ig, new object [] { t, true });
+       }
+
+       //
+       // Returns whether the array of memberinfos contains the given method
+       //
+       public static bool ArrayContainsMethod (MemberInfo [] array, MethodBase new_method)
+       {
+               Type [] new_args = TypeManager.GetArgumentTypes (new_method);
+               
+               foreach (MethodBase method in array) {
+                       if (method.Name != new_method.Name)
+                               continue;
+
+                        if (method is MethodInfo && new_method is MethodInfo)
+                                if (((MethodInfo) method).ReturnType != ((MethodInfo) new_method).ReturnType)
+                                        continue;
+
+                        
+                       Type [] old_args = TypeManager.GetArgumentTypes (method);
+                       int old_count = old_args.Length;
+                       int i;
+                       
+                       if (new_args.Length != old_count)
+                               continue;
+                       
+                       for (i = 0; i < old_count; i++){
+                               if (old_args [i] != new_args [i])
+                                       break;
+                       }
+                       if (i != old_count)
+                               continue;
+
+                       return true;
+               }
+                
+               return false;
+       }
+       
+       //
+       // We copy methods from `new_members' into `target_list' if the signature
+       // for the method from in the new list does not exist in the target_list
+       //
+       // The name is assumed to be the same.
+       //
+       public static ArrayList CopyNewMethods (ArrayList target_list, IList new_members)
+       {
+               if (target_list == null){
+                       target_list = new ArrayList ();
+
+                       foreach (MemberInfo mi in new_members){
+                               if (mi is MethodBase)
+                                       target_list.Add (mi);
+                       }
+                       return target_list;
+               }
+               
+               MemberInfo [] target_array = new MemberInfo [target_list.Count];
+               target_list.CopyTo (target_array, 0);
+               
+               foreach (MemberInfo mi in new_members){
+                       MethodBase new_method = (MethodBase) mi;
+                       
+                       if (!ArrayContainsMethod (target_array, new_method))
+                               target_list.Add (new_method);
+               }
+               return target_list;
+       }
+
+#region MemberLookup implementation
+       
+       //
+       // Whether we allow private members in the result (since FindMembers
+       // uses NonPublic for both protected and private), we need to distinguish.
+       //
+
+       static internal bool FilterNone (MemberInfo m, object filter_criteria)
+       {
+               return true;
+       }
+
+       internal class Closure {
+               internal bool     private_ok;
+
+               // Who is invoking us and which type is being queried currently.
+               internal Type     invocation_type;
+               internal Type     qualifier_type;
+
+               // The assembly that defines the type is that is calling us
+               internal Assembly invocation_assembly;
+               internal IList almost_match;
+
+               private bool CheckValidFamilyAccess (bool is_static, MemberInfo m)
+               {
+                       if (invocation_type == null)
+                               return false;
+
+                       if (is_static)
+                               return true;
+                       
+                       // A nested class has access to all the protected members visible
+                       // to its parent.
+                       if (qualifier_type != null
+                           && TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
+                               return true;
+
+                       if (invocation_type == m.DeclaringType
+                           || invocation_type.IsSubclassOf (m.DeclaringType)) {
+                               // Although a derived class can access protected members of
+                               // its base class it cannot do so through an instance of the
+                               // base class (CS1540).
+                               // => Ancestry should be: declaring_type ->* invocation_type
+                               //      ->*  qualified_type
+                               if (qualifier_type == null
+                                   || qualifier_type == invocation_type
+                                   || qualifier_type.IsSubclassOf (invocation_type))
+                                       return true;
+                       }
+       
+                       if (almost_match != null)
+                               almost_match.Add (m);
+                       return false;
+               }
+
+               bool Filter (MethodBase mb, object filter_criteria)
+               {
+                       MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
+
+                       if (ma == MethodAttributes.Private)
+                               return private_ok ||
+                                       IsPrivateAccessible (invocation_type, mb.DeclaringType) ||
+                                       IsNestedChildOf (invocation_type, mb.DeclaringType);
+
+                       //
+                       // FamAndAssem requires that we not only derivate, but we are on the
+                       // same assembly.  
+                       //
+                       if (ma == MethodAttributes.FamANDAssem){
+                               if (invocation_assembly != mb.DeclaringType.Assembly)
+                                       return false;
+                       }
+
+                       // Assembly and FamORAssem succeed if we're in the same assembly.
+                       if ((ma == MethodAttributes.Assembly) || (ma == MethodAttributes.FamORAssem)){
+                               if (invocation_assembly == mb.DeclaringType.Assembly)
+                                       return true;
+                       }
+
+                       // We already know that we aren't in the same assembly.
+                       if (ma == MethodAttributes.Assembly)
+                               return false;
+
+                       // Family and FamANDAssem require that we derive.
+                       if ((ma == MethodAttributes.Family) || (ma == MethodAttributes.FamANDAssem)){
+                               if (invocation_type == null)
+                                       return false;
+
+                               if (!IsNestedFamilyAccessible (invocation_type, mb.DeclaringType))
+                                       return false;
+
+                               // Although a derived class can access protected members of its base class
+                               // it cannot do so through an instance of the base class (CS1540).
+                               if (!mb.IsStatic && (qualifier_type != null) &&
+                                   !IsEqualGenericInstance (invocation_type, qualifier_type) &&
+                                   TypeManager.IsFamilyAccessible (invocation_type, qualifier_type) &&
+                                   !TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
+                                       return false;
+
+                               return true;
+                       }
+
+                       // Public.
+                       return true;
+               }
+
+               bool Filter (FieldInfo fi, object filter_criteria)
+               {
+                       FieldAttributes fa = fi.Attributes & FieldAttributes.FieldAccessMask;
+
+                       if (fa == FieldAttributes.Private)
+                               return private_ok ||
+                                       IsPrivateAccessible (invocation_type, fi.DeclaringType) ||
+                                       IsNestedChildOf (invocation_type, fi.DeclaringType);
+
+                       //
+                       // FamAndAssem requires that we not only derivate, but we are on the
+                       // same assembly.  
+                       //
+                       if (fa == FieldAttributes.FamANDAssem){
+                               if (invocation_assembly != fi.DeclaringType.Assembly)
+                                       return false;
+                       }
+
+                       // Assembly and FamORAssem succeed if we're in the same assembly.
+                       if ((fa == FieldAttributes.Assembly) || (fa == FieldAttributes.FamORAssem)){
+                               if (invocation_assembly == fi.DeclaringType.Assembly)
+                                       return true;
+                       }
+
+                       // We already know that we aren't in the same assembly.
+                       if (fa == FieldAttributes.Assembly)
+                               return false;
+
+                       // Family and FamANDAssem require that we derive.
+                       if ((fa == FieldAttributes.Family) || (fa == FieldAttributes.FamANDAssem)){
+                               if (invocation_type == null)
+                                       return false;
+
+                               if (!IsNestedFamilyAccessible (invocation_type, fi.DeclaringType))
+                                       return false;
+
+                               // Although a derived class can access protected members of its base class
+                               // it cannot do so through an instance of the base class (CS1540).
+                               if (!fi.IsStatic && (qualifier_type != null) &&
+                                   !IsEqualGenericInstance (invocation_type, qualifier_type) &&
+                                   TypeManager.IsFamilyAccessible (invocation_type, qualifier_type) &&
+                                   !TypeManager.IsNestedChildOf (invocation_type, qualifier_type))
+                                       return false;
+
+                               return true;
+                       }
+
+                       // Public.
+                       return true;
+               }
+               
+               //
+               // This filter filters by name + whether it is ok to include private
+               // members in the search
+               //
+               internal bool Filter (MemberInfo m, object filter_criteria)
+               {
+                       //
+                       // Hack: we know that the filter criteria will always be in the
+                       // `closure' // fields. 
+                       //
+
+                       if ((filter_criteria != null) && (m.Name != (string) filter_criteria))
+                               return false;
+
+                       if (((qualifier_type == null) || (qualifier_type == invocation_type)) &&
+                           (invocation_type != null) &&
+                           IsPrivateAccessible (m.DeclaringType, invocation_type))
+                               return true;
+
+                       //
+                       // Ugly: we need to find out the type of `m', and depending
+                       // on this, tell whether we accept or not
+                       //
+                       if (m is MethodBase)
+                               return Filter ((MethodBase) m, filter_criteria);
+
+                       if (m is FieldInfo)
+                               return Filter ((FieldInfo) m, filter_criteria);
+
+                       //
+                       // EventInfos and PropertyInfos, return true because they lack
+                       // permission information, so we need to check later on the methods.
+                       //
+                       return true;
+               }
+       }
+
+       static Closure closure = new Closure ();
+       static MemberFilter FilterWithClosure_delegate = new MemberFilter (closure.Filter);
+
+       //
+       // Looks up a member called `name' in the `queried_type'.  This lookup
+       // is done by code that is contained in the definition for `invocation_type'
+       // through a qualifier of type `qualifier_type' (or null if there is no qualifier).
+       //
+       // `invocation_type' is used to check whether we're allowed to access the requested
+       // member wrt its protection level.
+       //
+       // When called from MemberAccess, `qualifier_type' is the type which is used to access
+       // the requested member (`class B { A a = new A (); a.foo = 5; }'; here invocation_type
+       // is B and qualifier_type is A).  This is used to do the CS1540 check.
+       //
+       // When resolving a SimpleName, `qualifier_type' is null.
+       //
+       // The `qualifier_type' is used for the CS1540 check; it's normally either null or
+       // the same than `queried_type' - except when we're being called from BaseAccess;
+       // in this case, `invocation_type' is the current type and `queried_type' the base
+       // type, so this'd normally trigger a CS1540.
+       //
+       // The binding flags are `bf' and the kind of members being looked up are `mt'
+       //
+       // The return value always includes private members which code in `invocation_type'
+       // is allowed to access (using the specified `qualifier_type' if given); only use
+       // BindingFlags.NonPublic to bypass the permission check.
+       //
+       // The 'almost_match' argument is used for reporting error CS1540.
+       //
+       // Returns an array of a single element for everything but Methods/Constructors
+       // that might return multiple matches.
+       //
+       public static MemberInfo [] MemberLookup (Type invocation_type, Type qualifier_type,
+                                                 Type queried_type, MemberTypes mt,
+                                                 BindingFlags original_bf, string name, IList almost_match)
+       {
+               Timer.StartTimer (TimerType.MemberLookup);
+
+               MemberInfo[] retval = RealMemberLookup (invocation_type, qualifier_type,
+                                                       queried_type, mt, original_bf, name, almost_match);
+
+               Timer.StopTimer (TimerType.MemberLookup);
+
+               return retval;
+       }
+
+       static MemberInfo [] RealMemberLookup (Type invocation_type, Type qualifier_type,
+                                              Type queried_type, MemberTypes mt,
+                                              BindingFlags original_bf, string name, IList almost_match)
+       {
+               BindingFlags bf = original_bf;
+               
+               ArrayList method_list = null;
+               Type current_type = queried_type;
+               bool searching = (original_bf & BindingFlags.DeclaredOnly) == 0;
+               bool skip_iface_check = true, used_cache = false;
+               bool always_ok_flag = false;
+
+               closure.invocation_type = invocation_type;
+               closure.invocation_assembly = invocation_type != null ? invocation_type.Assembly : null;
+               closure.qualifier_type = qualifier_type;
+               closure.almost_match = almost_match;
+
+               //
+               // If we are a nested class, we always have access to our container
+               // type names
+               //
+               if (invocation_type != null){
+                       string invocation_name = invocation_type.FullName;
+                       if ((invocation_name != null) && (invocation_name.IndexOf ('+') != -1)){
+                               string container = queried_type.FullName + "+";
+                               int container_length = container.Length;
+
+                               if (invocation_name.Length > container_length){
+                                       string shared = invocation_name.Substring (0, container_length);
+                               
+                                       if (shared == container)
+                                               always_ok_flag = true;
+                               }
+                       }
+               }
+               
+               // This is from the first time we find a method
+               // in most cases, we do not actually find a method in the base class
+               // so we can just ignore it, and save the arraylist allocation
+               MemberInfo [] first_members_list = null;
+               bool use_first_members_list = false;
+               
+               do {
+                       MemberInfo [] list;
+
+                       //
+                       // `NonPublic' is lame, because it includes both protected and
+                       // private methods, so we need to control this behavior by
+                       // explicitly tracking if a private method is ok or not.
+                       //
+                       // The possible cases are:
+                       //    public, private and protected (internal does not come into the
+                       //    equation)
+                       //
+                       if ((invocation_type != null) &&
+                           ((invocation_type == current_type) ||
+                            IsNestedChildOf (invocation_type, current_type)) ||
+                           always_ok_flag)
+                               bf = original_bf | BindingFlags.NonPublic;
+                       else
+                               bf = original_bf;
+
+                       closure.private_ok = (original_bf & BindingFlags.NonPublic) != 0;
+
+                       Timer.StopTimer (TimerType.MemberLookup);
+
+                       list = MemberLookup_FindMembers (
+                               current_type, mt, bf, name, out used_cache);
+
+                       Timer.StartTimer (TimerType.MemberLookup);
+
+                       //
+                       // When queried for an interface type, the cache will automatically check all
+                       // inherited members, so we don't need to do this here.  However, this only
+                       // works if we already used the cache in the first iteration of this loop.
+                       //
+                       // If we used the cache in any further iteration, we can still terminate the
+                       // loop since the cache always looks in all parent classes.
+                       //
+
+                       if (used_cache)
+                               searching = false;
+                       else
+                               skip_iface_check = false;
+
+                       if (current_type == TypeManager.object_type)
+                               searching = false;
+                       else {
+                               current_type = current_type.BaseType;
+                               
+                               //
+                               // This happens with interfaces, they have a null
+                               // basetype.  Look members up in the Object class.
+                               //
+                               if (current_type == null) {
+                                       current_type = TypeManager.object_type;
+                                       searching = true;
+                               }
+                       }
+                       
+                       if (list.Length == 0)
+                               continue;
+
+                       //
+                       // Events and types are returned by both `static' and `instance'
+                       // searches, which means that our above FindMembers will
+                       // return two copies of the same.
+                       //
+                       if (list.Length == 1 && !(list [0] is MethodBase)){
+                               return list;
+                       }
+
+                       //
+                       // Multiple properties: we query those just to find out the indexer
+                       // name
+                       //
+                       if (list [0] is PropertyInfo)
+                               return list;
+
+                       //
+                       // We found an event: the cache lookup returns both the event and
+                       // its private field.
+                       //
+                       if (list [0] is EventInfo) {
+                               if ((list.Length == 2) && (list [1] is FieldInfo))
+                                       return new MemberInfo [] { list [0] };
+
+                               // Oooops
+                               return null;
+                       }
+
+                       //
+                       // We found methods, turn the search into "method scan"
+                       // mode.
+                       //
+
+                       if (first_members_list != null) {
+                               if (use_first_members_list) {
+                                       method_list = CopyNewMethods (method_list, first_members_list);
+                                       use_first_members_list = false;
+                               }
+                               
+                               method_list = CopyNewMethods (method_list, list);
+                       } else {
+                               first_members_list = list;
+                               use_first_members_list = true;
+
+                               mt &= (MemberTypes.Method | MemberTypes.Constructor);
+                       }
+               } while (searching);
+
+               if (use_first_members_list) {
+                       foreach (MemberInfo mi in first_members_list) {
+                               if (! (mi is MethodBase)) {
+                                       method_list = CopyNewMethods (method_list, first_members_list);
+                                       return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
+                               }
+                       }
+                       return (MemberInfo []) first_members_list;
+               }
+
+               if (method_list != null && method_list.Count > 0) {
+                        return (MemberInfo []) method_list.ToArray (typeof (MemberInfo));
+                }
+               //
+               // This happens if we already used the cache in the first iteration, in this case
+               // the cache already looked in all interfaces.
+               //
+               if (skip_iface_check)
+                       return null;
+
+               //
+               // Interfaces do not list members they inherit, so we have to
+               // scan those.
+               // 
+               if (!queried_type.IsInterface)
+                       return null;
+
+               if (queried_type.IsArray)
+                       queried_type = TypeManager.array_type;
+               
+               Type [] ifaces = GetInterfaces (queried_type);
+               if (ifaces == null)
+                       return null;
+               
+               foreach (Type itype in ifaces){
+                       MemberInfo [] x;
+
+                       x = MemberLookup (null, null, itype, mt, bf, name, null);
+                       if (x != null)
+                               return x;
+               }
+                                       
+               return null;
+       }
+
+       // Tests whether external method is really special
+       public static bool IsSpecialMethod (MethodBase mb)
+       {
+               string name = mb.Name;
+               if (name.StartsWith ("get_") || name.StartsWith ("set_"))
+                       return mb.DeclaringType.GetProperty (name.Substring (4)) != null;
+                               
+               if (name.StartsWith ("add_"))
+                       return mb.DeclaringType.GetEvent (name.Substring (4)) != null;
+
+               if (name.StartsWith ("remove_"))
+                       return mb.DeclaringType.GetEvent (name.Substring (7)) != null;
+
+               if (name.StartsWith ("op_")){
+                       foreach (string oname in Unary.oper_names) {
+                               if (oname == name)
+                                       return true;
+                       }
+
+                       foreach (string oname in Binary.oper_names) {
+                               if (oname == name)
+                                       return true;
+                       }
+               }
+               return false;
+       }
+               
+#endregion
+       
+}
+
+/// <summary>
+///   There is exactly one instance of this class per type.
+/// </summary>
+public sealed class TypeHandle : IMemberContainer {
+       public readonly TypeHandle BaseType;
+
+       readonly int id = ++next_id;
+       static int next_id = 0;
+
+       /// <summary>
+       ///   Lookup a TypeHandle instance for the given type.  If the type doesn't have
+       ///   a TypeHandle yet, a new instance of it is created.  This static method
+       ///   ensures that we'll only have one TypeHandle instance per type.
+       /// </summary>
+       private static TypeHandle GetTypeHandle (Type t)
+       {
+               TypeHandle handle = (TypeHandle) type_hash [t];
+               if (handle != null)
+                       return handle;
+
+               handle = new TypeHandle (t);
+               type_hash.Add (t, handle);
+               return handle;
+       }
+
+       public static MemberCache GetMemberCache (Type t)
+       {
+               return GetTypeHandle (t).MemberCache;
+       }
+       
+       public static void CleanUp ()
+       {
+               type_hash = null;
+       }
+
+       /// <summary>
+       ///   Returns the TypeHandle for TypeManager.object_type.
+       /// </summary>
+       public static IMemberContainer ObjectType {
+               get {
+                       if (object_type != null)
+                               return object_type;
+
+                       object_type = GetTypeHandle (TypeManager.object_type);
+
+                       return object_type;
+               }
+       }
+
+       /// <summary>
+       ///   Returns the TypeHandle for TypeManager.array_type.
+       /// </summary>
+       public static IMemberContainer ArrayType {
+               get {
+                       if (array_type != null)
+                               return array_type;
+
+                       array_type = GetTypeHandle (TypeManager.array_type);
+
+                       return array_type;
+               }
+       }
+
+       private static PtrHashtable type_hash = new PtrHashtable ();
+
+       private static TypeHandle object_type = null;
+       private static TypeHandle array_type = null;
+
+       private Type type;
+       private string full_name;
+       private bool is_interface;
+       private MemberCache member_cache;
+       private MemberCache parent_cache;
+
+       private TypeHandle (Type type)
+       {
+               this.type = type;
+               full_name = type.FullName != null ? type.FullName : type.Name;
+               if (type.BaseType != null) {
+                       BaseType = GetTypeHandle (type.BaseType);
+                       parent_cache = BaseType.MemberCache;
+               } else if (type.IsInterface)
+                       parent_cache = TypeManager.LookupParentInterfacesCache (type);
+               this.is_interface = type.IsInterface || type.IsGenericParameter;
+               this.member_cache = new MemberCache (this);
+       }
+
+       // IMemberContainer methods
+
+       public string Name {
+               get {
+                       return full_name;
+               }
+       }
+
+       public Type Type {
+               get {
+                       return type;
+               }
+       }
+
+       public MemberCache ParentCache {
+               get {
+                       return parent_cache;
+               }
+       }
+
+       public bool IsInterface {
+               get {
+                       return is_interface;
+               }
+       }
+
+       public MemberList GetMembers (MemberTypes mt, BindingFlags bf)
+       {
+                MemberInfo [] members;
+               if (type is GenericTypeParameterBuilder)
+                       return MemberList.Empty;
+               if (mt == MemberTypes.Event)
+                        members = type.GetEvents (bf | BindingFlags.DeclaredOnly);
+                else
+                        members = type.FindMembers (mt, bf | BindingFlags.DeclaredOnly,
+                                                    null, null);
+                Array.Reverse (members);
+
+                return new MemberList (members);
+       }
+
+       // IMemberFinder methods
+
+       public MemberList FindMembers (MemberTypes mt, BindingFlags bf, string name,
+                                      MemberFilter filter, object criteria)
+       {
+               return new MemberList (member_cache.FindMembers (mt, bf, name, filter, criteria));
+       }
+
+       public MemberCache MemberCache {
+               get {
+                       return member_cache;
+               }
+       }
+
+       public override string ToString ()
+       {
+               if (BaseType != null)
+                       return "TypeHandle (" + id + "," + Name + " : " + BaseType + ")";
+               else
+                       return "TypeHandle (" + id + "," + Name + ")";
+       }
+}
+
+}