2010-01-14 Marek Safar <marek.safar@gmail.com>
authorMarek Safar <marek.safar@gmail.com>
Thu, 14 Jan 2010 12:24:47 +0000 (12:24 -0000)
committerMarek Safar <marek.safar@gmail.com>
Thu, 14 Jan 2010 12:24:47 +0000 (12:24 -0000)
* membercache.cs: Extracted from decl.cs.

* *.cs: Put more infrastructure in place.

svn path=/trunk/mcs/; revision=149550

13 files changed:
1  2 
mcs/mcs/ChangeLog
mcs/mcs/decl.cs
mcs/mcs/dmcs.csproj
mcs/mcs/dmcs.exe.sources
mcs/mcs/enum.cs
mcs/mcs/field.cs
mcs/mcs/gmcs.exe.sources
mcs/mcs/import.cs
mcs/mcs/membercache.cs
mcs/mcs/method.cs
mcs/mcs/property.cs
mcs/mcs/smcs.exe.sources
mcs/mcs/typespec.cs

index e04e4ec63f355458301bdc2225a1c4e6901209a6,10e492c93c06a9bdd68d615bb89943870023fe94..7d1e7b5202af414290bde30188f7b44376fa4098
@@@ -1,11 -1,3 +1,17 @@@
++2010-01-14  Marek Safar  <marek.safar@gmail.com>
++
++      * membercache.cs: Extracted from decl.cs.
++      
++      * *.cs: Put more infrastructure in place.
++
 +2010-01-13  Marek Safar  <marek.safar@gmail.com>
 +
 +      * *.cs: Add property specification, unused yet.
 +
 +2010-01-13  Marek Safar  <marek.safar@gmail.com>
 +
 +      * property.cs: Move all property based declarations into a new file.
 +
  2010-01-13  Marek Safar  <marek.safar at gmail.com>
  
        * expression.cs (Conditional): Resolve reduced expression.
diff --cc mcs/mcs/decl.cs
index 270c7c4f5e89d818524cfd8cbe52371fbe8299c2,270c7c4f5e89d818524cfd8cbe52371fbe8299c2..e50aba11aaffc769af2a7bcf1a014160620f9c6e
@@@ -901,8 -901,8 +901,9 @@@ namespace Mono.CSharp 
                readonly string name;
                StateFlags state;
                protected IMemberDefinition definition;
++              public readonly MemberKind Kind;
  
--              protected MemberSpec (IMemberDefinition definition, string name, Modifiers modifiers)
++              protected MemberSpec (MemberKind kind, IMemberDefinition definition, string name, Modifiers modifiers)
                {
                        this.definition = definition;
                        this.name = name;
                        return true;
                }
        }
--
--      /// <summary>
--      ///   This is a readonly list of MemberInfo's.      
--      /// </summary>
--      public class MemberList : IList<MemberInfo> {
--              public readonly IList<MemberInfo> List;
--              int count;
--
--              /// <summary>
--              ///   Create a new MemberList from the given IList.
--              /// </summary>
--              public MemberList (IList<MemberInfo> list)
--              {
--                      if (list != null)
--                              this.List = list;
--                      else
--                              this.List = new List<MemberInfo> ();
--                      count = List.Count;
--              }
--
--              /// <summary>
--              ///   Concatenate the ILists `first' and `second' to a new MemberList.
--              /// </summary>
--              public MemberList (IList<MemberInfo> first, IList<MemberInfo> second)
--              {
--                      var list = new List<MemberInfo> ();
--                      list.AddRange (first);
--                      list.AddRange (second);
--                      count = list.Count;
--                      List = list;
--              }
--
--              public static readonly MemberList Empty = new MemberList (Array.AsReadOnly (new MemberInfo[0]));
--
--              /// <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 void CopyTo (MemberInfo[] array, int index)
--              {
--                      List.CopyTo (array, index);
--              }
--
--              // IEnumerable
--
--              public IEnumerator<MemberInfo> GetEnumerator ()
--              {
--                      return List.GetEnumerator ();
--              }
--
--              System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
--              {
--                      return List.GetEnumerator ();
--              }
--
--              // IList
--
--              public bool IsFixedSize {
--                      get {
--                              return true;
--                      }
--              }
--
--              public bool IsReadOnly {
--                      get {
--                              return true;
--                      }
--              }
--
--              MemberInfo IList<MemberInfo>.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 void Add (MemberInfo value)
--              {
--                      throw new NotSupportedException ();
--              }
--
--              public void Clear ()
--              {
--                      throw new NotSupportedException ();
--              }
--
--              public bool Contains (MemberInfo value)
--              {
--                      return List.Contains (value);
--              }
--
--              public int IndexOf (MemberInfo value)
--              {
--                      return List.IndexOf (value);
--              }
--
--              public void Insert (int index, MemberInfo value)
--              {
--                      throw new NotSupportedException ();
--              }
--
--              public bool Remove (MemberInfo 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 base 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 base class.
--              /// </summary>
--              MemberCache BaseCache {
--                      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>
--      ///   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 Dictionary<string, List<CacheEntry>> member_hash;
--              protected Dictionary<string, List<CacheEntry>> method_hash;
--
--              Dictionary<string, object> locase_table;
--
--              static List<MethodInfo> overrides = new List<MethodInfo> ();
--
--              /// <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 base class (we have a base class unless we're
--                      // TypeManager.object_type), we deep-copy its MemberCache here.
--                      if (Container.BaseCache != null)
--                              member_hash = SetupCache (Container.BaseCache);
--                      else
--                              member_hash = new Dictionary<string, List<CacheEntry>> ();
--
--                      // 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.IsGenericType && (type.GetGenericTypeDefinition () is TypeBuilder)) &&
--                          !TypeManager.IsGenericType (type) && !TypeManager.IsGenericParameter (type) &&
--                          (Container.BaseCache == null || Container.BaseCache.method_hash != null)) {
--                                      method_hash = new Dictionary<string, List<CacheEntry>> ();
--                                      AddMethods (type);
--                      }
--
--                      // Add all members from the current class.
--                      AddMembers (Container);
--
--                      Timer.StopTimer (TimerType.CacheInit);
--              }
--
--              public MemberCache (Type baseType, IMemberContainer container)
--              {
--                      this.Container = container;
--                      if (baseType == null)
--                              this.member_hash = new Dictionary<string, List<CacheEntry>> ();
--                      else
--                              this.member_hash = SetupCache (TypeManager.LookupMemberCache (baseType));
--              }
--
--              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 Dictionary<string, List<CacheEntry>> ();
--                      if (ifaces == null)
--                              return;
--
--                      foreach (Type itype in ifaces)
--                              AddCacheContents (TypeManager.LookupMemberCache (itype));
--              }
--
--              public MemberCache (IMemberContainer container, Type base_class, Type[] ifaces)
--              {
--                      this.Container = container;
--
--                      // If we have a base class (we have a base class unless we're
--                      // TypeManager.object_type), we deep-copy its MemberCache here.
--                      if (Container.BaseCache != null)
--                              member_hash = SetupCache (Container.BaseCache);
--                      else
--                              member_hash = new Dictionary<string, List<CacheEntry>> ();
--
--                      if (base_class != null)
--                              AddCacheContents (TypeManager.LookupMemberCache (base_class));
--                      if (ifaces != null) {
--                              foreach (Type itype in ifaces) {
--                                      MemberCache cache = TypeManager.LookupMemberCache (itype);
--                                      if (cache != null)
--                                              AddCacheContents (cache);
--                              }
--                      }
--              }
--
--              /// <summary>
--              ///   Bootstrap this member cache by doing a deep-copy of our base.
--              /// </summary>
--              static Dictionary<string, List<CacheEntry>> SetupCache (MemberCache base_class)
--              {
--                      if (base_class == null)
--                              return new Dictionary<string, List<CacheEntry>> ();
--
--                      var hash = new Dictionary<string, List<CacheEntry>> (base_class.member_hash.Count);
--                      var it = base_class.member_hash.GetEnumerator ();
--                      while (it.MoveNext ()) {
--                              hash.Add (it.Current.Key, new List<CacheEntry> (it.Current.Value));
--                      }
--                                
--                      return hash;
--              }
--              
--              //
--              // Converts ModFlags to BindingFlags
--              //
--              static BindingFlags GetBindingFlags (Modifiers modifiers)
--              {
--                      BindingFlags bf;
--                      if ((modifiers & Modifiers.STATIC) != 0)
--                              bf = BindingFlags.Static;
--                      else
--                              bf = BindingFlags.Instance;
--
--                      if ((modifiers & Modifiers.PRIVATE) != 0)
--                              bf |= BindingFlags.NonPublic;
--                      else
--                              bf |= BindingFlags.Public;
--
--                      return bf;
--              }               
--
--              /// <summary>
--              ///   Add the contents of `cache' to the member_hash.
--              /// </summary>
--              void AddCacheContents (MemberCache cache)
--              {
--                      var it = cache.member_hash.GetEnumerator ();
--                      while (it.MoveNext ()) {
--                              List<CacheEntry> list;
--                              if (!member_hash.TryGetValue (it.Current.Key, out list))
--                                      member_hash [it.Current.Key] = list = new List<CacheEntry> ();
--
--                              var entries = it.Current.Value;
--                              for (int i = entries.Count-1; i >= 0; i--) {
--                                      var entry = 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);
--              }
--
--              public void AddMember (MemberInfo mi, MemberCore mc)
--              {
--                      AddMember (mi.MemberType, GetBindingFlags (mc.ModFlags), Container, mi.Name, mi);
--              }
--
--              public void AddGenericMember (MemberInfo mi, InterfaceMemberBase mc)
--              {
--                      AddMember (mi.MemberType, GetBindingFlags (mc.ModFlags), Container,
--                              MemberName.MakeName (mc.GetFullName (mc.MemberName), mc.MemberName.TypeArguments), mi);
--              }
--
--              public void AddNestedType (DeclSpace type)
--              {
--                      AddMember (MemberTypes.NestedType, GetBindingFlags (type.ModFlags), (IMemberContainer) type.Parent,
--                              type.TypeBuilder.Name, type.TypeBuilder);
--              }
--
--              public void AddInterface (MemberCache baseCache)
--              {
--                      if (baseCache.member_hash.Count > 0)
--                              AddCacheContents (baseCache);
--              }
--
--              void AddMember (MemberTypes mt, BindingFlags bf, IMemberContainer container,
--                              string name, MemberInfo member)
--              {
--                      // We use a name-based hash table of ArrayList's.
--                      List<CacheEntry> list;
--                      if (!member_hash.TryGetValue (name, out list)) {
--                              list = new List<CacheEntry> (1);
--                              member_hash.Add (name, list);
--                      }
--
--                      // When this method is called for the current class, the list will
--                      // already contain all inherited members from our base 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 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;
--
--                              AddMember (mt, bf, container, name, member);
--
--                              if (member is MethodInfo) {
--                                      string gname = TypeManager.GetMethodName ((MethodInfo) member);
--                                      if (gname != name)
--                                              AddMember (mt, bf, container, gname, member);
--                              }
--                      }
--              }
--
--              /// <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)
--              {
--                      MethodBase [] 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.
--                              List<CacheEntry> list;
--                              if (!method_hash.TryGetValue (name, out list)) {
--                                      list = new List<CacheEntry> (1);
--                                      method_hash.Add (name, list);
--                              }
--
--                              MethodInfo curr = (MethodInfo) member;
--                              while (curr.IsVirtual && (curr.Attributes & MethodAttributes.NewSlot) == 0) {
--                                      MethodInfo base_method = curr.GetBaseDefinition ();
--
--                                      if (base_method == curr)
--                                              // Not every virtual function needs to have a NewSlot flag.
--                                              break;
--
--                                      overrides.Add (curr);
--                                      list.Add (new CacheEntry (null, base_method, MemberTypes.Method, bf));
--                                      curr = base_method;
--                              }
--
--                              if (overrides.Count > 0) {
--                                      for (int i = 0; i < overrides.Count; ++i)
--                                              TypeManager.RegisterOverride ((MethodBase) overrides [i], curr);
--                                      overrides.Clear ();
--                              }
--
--                              // 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]
--              public 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,
--
--                      NotExtensionMethod      = 0x800,
--
--                      MaskType        = Constructor|Event|Field|Method|Property|NestedType
--              }
--
--              public class CacheEntry {
--                      public readonly IMemberContainer Container;
--                      public 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 (IList<MemberInfo> 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>
--              List<MemberInfo> global = new List<MemberInfo> ();
--              bool using_global;
--              
--              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);
--
--                      List<CacheEntry> 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))
--                              method_hash.TryGetValue (name, out applicable);
--                      else
--                              member_hash.TryGetValue (name, out applicable);
--
--                      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;
--
--                      bool do_interface_search = current.IsInterface;
--
--                      // `applicable' is a list of all members with the given member name `name'
--                      // in the current class and all its base 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 base).
--
--                      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)
--                                              break;
--
--                                      if (!do_interface_search && 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;
--                                      }
--                                      
--                                      // Because interfaces support multiple inheritance we have to be sure that
--                                      // base member is from same interface, so only top level member will be returned
--                                      if (do_interface_search && global.Count > 0) {
--                                              bool member_already_exists = false;
--
--                                              foreach (MemberInfo mi in global) {
--                                                      if (mi is MethodBase)
--                                                              continue;
--
--                                                      if (IsInterfaceBaseInterface (TypeManager.GetInterfaces (mi.DeclaringType), entry.Member.DeclaringType)) {
--                                                              member_already_exists = true;
--                                                              break;
--                                                      }
--                                              }
--                                              if (member_already_exists)
--                                                      continue;
--                                      }
--
--                                      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;
--              }
--
--              /// <summary>
--              /// Returns true if iterface exists in any base interfaces (ifaces)
--              /// </summary>
--              static bool IsInterfaceBaseInterface (Type[] ifaces, Type ifaceToFind)
--              {
--                      foreach (Type iface in ifaces) {
--                              if (iface == ifaceToFind)
--                                      return true;
--
--                              Type[] base_ifaces = TypeManager.GetInterfaces (iface);
--                              if (base_ifaces.Length > 0 && IsInterfaceBaseInterface (base_ifaces, ifaceToFind))
--                                      return true;
--                      }
--                      return false;
--              }
--              
--              // find the nested type @name in @this.
--              public Type FindNestedType (string name)
--              {
--                      List<CacheEntry> applicable;
--                      if (!member_hash.TryGetValue (name, out applicable))
--                              return null;
--                      
--                      for (int i = applicable.Count-1; i >= 0; i--) {
--                              CacheEntry entry = applicable [i];
--                              if ((entry.EntryType & EntryType.NestedType & EntryType.MaskType) != 0)
--                                      return (Type) entry.Member;
--                      }
--                      
--                      return null;
--              }
--
--              public MemberInfo FindBaseEvent (Type invocation_type, string name)
--              {
--                      List<CacheEntry> applicable;
--                      if (!member_hash.TryGetValue (name, out applicable))
--                              return null;
--
--                      //
--                      // Walk the chain of events, starting from the top.
--                      //
--                      for (int i = applicable.Count - 1; i >= 0; i--) 
--                      {
--                              CacheEntry entry = applicable [i];
--                              if ((entry.EntryType & EntryType.Event) == 0)
--                                      continue;
--                              
--                              EventInfo ei = (EventInfo)entry.Member;
--                              return ei.GetAddMethod (true);
--                      }
--
--                      return null;
--              }
--
--              //
--              // Looks for extension methods with defined name and extension type
--              //
--              public List<MethodSpec> FindExtensionMethods (Assembly thisAssembly, Type extensionType, string name, bool publicOnly)
--              {
--                      List<CacheEntry> entries;
--                      if (method_hash != null)
--                              method_hash.TryGetValue (name, out entries);
--                      else {
--                              member_hash.TryGetValue (name, out entries);
--                      }
--
--                      if (entries == null)
--                              return null;
--
--                      EntryType entry_type = EntryType.Static | EntryType.Method | EntryType.NotExtensionMethod;
--                      EntryType found_entry_type = entry_type & ~EntryType.NotExtensionMethod;
--
--                      List<MethodSpec> candidates = null;
--                      foreach (CacheEntry entry in entries) {
--                              if ((entry.EntryType & entry_type) == found_entry_type) {
--                                      MethodBase mb = (MethodBase)entry.Member;
--
--                                      // Simple accessibility check
--                                      if ((entry.EntryType & EntryType.Public) == 0 && publicOnly) {
--                                              MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
--                                              if (ma != MethodAttributes.Assembly && ma != MethodAttributes.FamORAssem)
--                                                      continue;
--                                              
--                                              if (!TypeManager.IsThisOrFriendAssembly (thisAssembly, mb.DeclaringType.Assembly))
--                                                      continue;
--                                      }
--
--                                      IMethodData md = TypeManager.GetMethod (mb);
--                                      AParametersCollection pd = md == null ?
--                                              TypeManager.GetParameterData (mb) : md.ParameterInfo;
--
--                                      Type ex_type = pd.ExtensionMethodType;
--                                      if (ex_type == null) {
--                                              entry.EntryType |= EntryType.NotExtensionMethod;
--                                              continue;
--                                      }
--
--                                      if (candidates == null)
--                                              candidates = new List<MethodSpec> (2);
--                                      candidates.Add (Import.CreateMethod (mb));
--                              }
--                      }
--
--                      return candidates;
--              }
--              
--              //
--              // This finds the method or property for us to override. invocation_type is the type where
--              // the override is going to be declared, name is the name of the method/property, and
--              // param_types 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 invocation_type, string name, AParametersCollection parameters, GenericMethod generic_method, bool is_property)
--              {
--                      List<CacheEntry> applicable;
--                      if (method_hash != null && !is_property)
--                              method_hash.TryGetValue (name, out applicable);
--                      else
--                              member_hash.TryGetValue (name, out applicable);
--                      
--                      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 = applicable [i];
--                              
--                              if ((entry.EntryType & (is_property ? (EntryType.Property | EntryType.Field) : EntryType.Method)) == 0)
--                                      continue;
--
--                              PropertyInfo pi = null;
--                              MethodInfo mi = null;
--                              FieldInfo fi = null;
--                              AParametersCollection cmp_attrs;
--                              
--                              if (is_property) {
--                                      if ((entry.EntryType & EntryType.Field) != 0) {
--                                              fi = (FieldInfo)entry.Member;
--                                              cmp_attrs = ParametersCompiled.EmptyReadOnlyParameters;
--                                      } else {
--                                              pi = (PropertyInfo) entry.Member;
--                                              cmp_attrs = TypeManager.GetParameterData (pi);
--                                      }
--                              } else {
--                                      mi = (MethodInfo) entry.Member;
--                                      cmp_attrs = TypeManager.GetParameterData (mi);
--                              }
--
--                              if (fi != null) {
--                                      // TODO: Almost duplicate !
--                                      // Check visibility
--                                      switch (fi.Attributes & FieldAttributes.FieldAccessMask) {
--                                      case FieldAttributes.PrivateScope:
--                                              continue;
--                                      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 (!invocation_type.Equals (entry.Container.Type) &&
--                                                  !TypeManager.IsNestedChildOf (invocation_type, entry.Container.Type))
--                                                      continue;
--                                              break;
--                                      case FieldAttributes.FamANDAssem:
--                                      case FieldAttributes.Assembly:
--                                              //
--                                              // Check for assembly methods
--                                              //
--                                              if (fi.DeclaringType.Assembly != CodeGen.Assembly.Builder)
--                                                      continue;
--                                              break;
--                                      }
--                                      return entry.Member;
--                              }
--
--                              //
--                              // Check the arguments
--                              //
--                              if (cmp_attrs.Count != parameters.Count)
--                                      continue;
--      
--                              int j;
--                              for (j = 0; j < cmp_attrs.Count; ++j) {
--                                      //
--                                      // LAMESPEC: No idea why `params' modifier is ignored
--                                      //
--                                      if ((parameters.FixedParameters [j].ModFlags & ~Parameter.Modifier.PARAMS) != 
--                                              (cmp_attrs.FixedParameters [j].ModFlags & ~Parameter.Modifier.PARAMS))
--                                              break;
--
--                                      if (!TypeManager.IsEqual (parameters.Types [j], cmp_attrs.Types [j]))
--                                              break;
--                              }
--
--                              if (j < cmp_attrs.Count)
--                                      continue;
--
--                              //
--                              // check generic arguments for methods
--                              //
--                              if (mi != null) {
--                                      Type [] cmpGenArgs = TypeManager.GetGenericArguments (mi);
--                                      if (generic_method == null && cmpGenArgs != null && cmpGenArgs.Length != 0)
--                                              continue;
--                                      if (generic_method != null && cmpGenArgs != null && cmpGenArgs.Length != generic_method.TypeParameters.Length)
--                                              continue;
--                              }
--
--                              //
--                              // 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.PrivateScope:
--                                      continue;
--                              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 (!invocation_type.Equals (entry.Container.Type) &&
--                                          !TypeManager.IsNestedChildOf (invocation_type, entry.Container.Type))
--                                              continue;
--                                      break;
--                              case MethodAttributes.FamANDAssem:
--                              case MethodAttributes.Assembly:
--                                      //
--                                      // Check for assembly methods
--                                      //
--                                      if (!TypeManager.IsThisOrFriendAssembly (invocation_type.Assembly, mi.DeclaringType.Assembly))
--                                              continue;
--                                      break;
--                              }
--                              return entry.Member;
--                      }
--                      
--                      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)
--              {
--                      List<CacheEntry> applicable = null;
-- 
--                      if (method_hash != null)
--                              method_hash.TryGetValue (name, out applicable);
-- 
--                      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;
--
--                      if (member_hash.TryGetValue (name, out applicable)) {
--                              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) {
--                                                              AParametersCollection arg_types = TypeManager.GetParameterData ((PropertyInfo)entry.Member);
--                                                              if (arg_types.Count > 0)
--                                                                      continue;
--                                                      }
--                                              }
--                                              return entry.Member;
--                                      }
--                              }
--                      }
--                      return null;
--              }
--
--
--              /// <summary>
--              /// Builds low-case table for CLS Compliance test
--              /// </summary>
--              public Dictionary<string, object> GetPublicMembers ()
--              {
--                      if (locase_table != null)
--                              return locase_table;
--
--                      locase_table = new Dictionary<string, object> ();
--                      foreach (var entry in member_hash) {
--                              var members = entry.Value;
--                              for (int ii = 0; ii < members.Count; ++ii) {
--                                      CacheEntry member_entry = 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 IDictionary<string, List<CacheEntry>> 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>
--              /// 
--              // TODO: refactor as method is always 'this'
--              public static void VerifyClsParameterConflict (IList<CacheEntry> al, MethodCore method, MemberInfo this_builder, Report Report)
--              {
--                      EntryType tested_type = (method is Constructor ? EntryType.Constructor : EntryType.Method) | EntryType.Public;
-- 
--                      for (int i = 0; i < al.Count; ++i) {
--                              var entry = 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;
--                              AttributeTester.Result result = AttributeTester.AreOverloadedMethodParamsClsCompliant (
--                                      method.Parameters, TypeManager.GetParameterData (method_to_compare));
--
--                              if (result == AttributeTester.Result.Ok)
--                                      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.IsClsComplianceRequired ())
--                                      continue;
--              
--                              Report.SymbolRelatedToPreviousError (entry.Member);
--                              switch (result) {
--                              case AttributeTester.Result.RefOutArrayError:
--                                      Report.Warning (3006, 1, method.Location,
--                                                      "Overloaded method `{0}' differing only in ref or out, or in array rank, is not CLS-compliant",
--                                                      method.GetSignatureForError ());
--                                      continue;
--                              case AttributeTester.Result.ArrayArrayError:
--                                      Report.Warning (3007, 1, method.Location,
--                                                      "Overloaded method `{0}' differing only by unnamed array types is not CLS-compliant",
--                                                      method.GetSignatureForError ());
--                                      continue;
--                              }
--
--                              throw new NotImplementedException (result.ToString ());
--                      }
--              }
--
--              public bool CheckExistingMembersOverloads (MemberCore member, string name, ParametersCompiled parameters, Report Report)
--              {
--                      List<CacheEntry> entries;
--                      if (!member_hash.TryGetValue (name, out entries))
--                              return true;
--
--                      int method_param_count = parameters.Count;
--                      for (int i = entries.Count - 1; i >= 0; --i) {
--                              CacheEntry ce = (CacheEntry) entries [i];
--
--                              if (ce.Container != member.Parent.PartialContainer)
--                                      return true;
--
--                              Type [] p_types;
--                              AParametersCollection pd;
--                              if ((ce.EntryType & EntryType.Property) != 0) {
--                                      pd = TypeManager.GetParameterData ((PropertyInfo) ce.Member);
--                                      p_types = pd.Types;
--                              } else {
--                                      MethodBase mb = (MethodBase) ce.Member;
--              
--                                      // TODO: This is more like a hack, because we are adding generic methods
--                                      // twice with and without arity name
--                                      if (TypeManager.IsGenericMethod (mb) && !member.MemberName.IsGeneric)
--                                              continue;
--
--                                      pd = TypeManager.GetParameterData (mb);
--                                      p_types = pd.Types;
--                              }
--
--                              if (p_types.Length != method_param_count)
--                                      continue;
--
--                              if (method_param_count > 0) {
--                                      int ii = method_param_count - 1;
--                                      Type type_a, type_b;
--                                      do {
--                                              type_a = parameters.Types [ii];
--                                              type_b = p_types [ii];
--
--                                              if (TypeManager.IsGenericParameter (type_a) && type_a.DeclaringMethod != null)
--                                                      type_a = typeof (TypeParameter);
--
--                                              if (TypeManager.IsGenericParameter (type_b) && type_b.DeclaringMethod != null)
--                                                      type_b = typeof (TypeParameter);
--
--                                              if ((pd.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF) !=
--                                                      (parameters.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF))
--                                                      break;
--
--                                      } while (TypeManager.IsEqual (type_a, type_b) && ii-- != 0);
--
--                                      if (ii >= 0)
--                                              continue;
--
--                                      //
--                                      // Operators can differ in return type only
--                                      //
--                                      if (member is Operator) {
--                                              Operator op = TypeManager.GetMethod ((MethodBase) ce.Member) as Operator;
--                                              if (op != null && op.ReturnType != ((Operator) member).ReturnType)
--                                                      continue;
--                                      }
--
--                                      //
--                                      // Report difference in parameter modifiers only
--                                      //
--                                      if (pd != null && member is MethodCore) {
--                                              ii = method_param_count;
--                                              while (ii-- != 0 && parameters.FixedParameters [ii].ModFlags == pd.FixedParameters [ii].ModFlags &&
--                                                      parameters.ExtensionMethodType == pd.ExtensionMethodType);
--
--                                              if (ii >= 0) {
--                                                      MethodCore mc = TypeManager.GetMethod ((MethodBase) ce.Member) as MethodCore;
--                                                      Report.SymbolRelatedToPreviousError (ce.Member);
--                                                      if ((member.ModFlags & Modifiers.PARTIAL) != 0 && (mc.ModFlags & Modifiers.PARTIAL) != 0) {
--                                                              if (parameters.HasParams || pd.HasParams) {
--                                                                      Report.Error (758, member.Location,
--                                                                              "A partial method declaration and partial method implementation cannot differ on use of `params' modifier");
--                                                              } else {
--                                                                      Report.Error (755, member.Location,
--                                                                              "A partial method declaration and partial method implementation must be both an extension method or neither");
--                                                              }
--                                                      } else {
--                                                              if (member is Constructor) {
--                                                                      Report.Error (851, member.Location,
--                                                                              "Overloaded contructor `{0}' cannot differ on use of parameter modifiers only",
--                                                                              member.GetSignatureForError ());
--                                                              } else {
--                                                                      Report.Error (663, member.Location,
--                                                                              "Overloaded method `{0}' cannot differ on use of parameter modifiers only",
--                                                                              member.GetSignatureForError ());
--                                                              }
--                                                      }
--                                                      return false;
--                                              }
--                                      }
--                              }
--
--                              if ((ce.EntryType & EntryType.Method) != 0) {
--                                      Method method_a = member as Method;
--                                      Method method_b = TypeManager.GetMethod ((MethodBase) ce.Member) as Method;
--                                      if (method_a != null && method_b != null && (method_a.ModFlags & method_b.ModFlags & Modifiers.PARTIAL) != 0) {
--                                              const Modifiers partial_modifiers = Modifiers.STATIC | Modifiers.UNSAFE;
--                                              if (method_a.IsPartialDefinition == method_b.IsPartialImplementation) {
--                                                      if ((method_a.ModFlags & partial_modifiers) == (method_b.ModFlags & partial_modifiers) ||
--                                                              method_a.Parent.IsUnsafe && method_b.Parent.IsUnsafe) {
--                                                              if (method_a.IsPartialImplementation) {
--                                                                      method_a.SetPartialDefinition (method_b);
--                                                                      entries.RemoveAt (i);
--                                                              } else {
--                                                                      method_b.SetPartialDefinition (method_a);
--                                                                      method_a.caching_flags |= MemberCore.Flags.PartialDefinitionExists;
--                                                              }
--                                                              continue;
--                                                      }
--
--                                                      if ((method_a.ModFlags & Modifiers.STATIC) != (method_b.ModFlags & Modifiers.STATIC)) {
--                                                              Report.SymbolRelatedToPreviousError (ce.Member);
--                                                              Report.Error (763, member.Location,
--                                                                      "A partial method declaration and partial method implementation must be both `static' or neither");
--                                                      }
--
--                                                      Report.SymbolRelatedToPreviousError (ce.Member);
--                                                      Report.Error (764, member.Location,
--                                                              "A partial method declaration and partial method implementation must be both `unsafe' or neither");
--                                                      return false;
--                                              }
--
--                                              Report.SymbolRelatedToPreviousError (ce.Member);
--                                              if (method_a.IsPartialDefinition) {
--                                                      Report.Error (756, member.Location, "A partial method `{0}' declaration is already defined",
--                                                              member.GetSignatureForError ());
--                                              } else {
--                                                      Report.Error (757, member.Location, "A partial method `{0}' implementation is already defined",
--                                                              member.GetSignatureForError ());
--                                              }
--
--                                              return false;
--                                      }
--
--                                      Report.SymbolRelatedToPreviousError (ce.Member);
--                                      IMethodData duplicate_member = TypeManager.GetMethod ((MethodBase) ce.Member);
--                                      if (member is Operator && duplicate_member is Operator) {
--                                              Report.Error (557, member.Location, "Duplicate user-defined conversion in type `{0}'",
--                                                      member.Parent.GetSignatureForError ());
--                                              return false;
--                                      }
--
--                                      bool is_reserved_a = member is AbstractPropertyEventMethod || member is Operator;
--                                      bool is_reserved_b = duplicate_member is AbstractPropertyEventMethod || duplicate_member is Operator;
--
--                                      if (is_reserved_a || is_reserved_b) {
--                                              Report.Error (82, member.Location, "A member `{0}' is already reserved",
--                                                      is_reserved_a ?
--                                                      TypeManager.GetFullNameSignature (ce.Member) :
--                                                      member.GetSignatureForError ());
--                                              return false;
--                                      }
--                              } else {
--                                      Report.SymbolRelatedToPreviousError (ce.Member);
--                              }
--                              
--                              Report.Error (111, member.Location,
--                                      "A member `{0}' is already defined. Rename this member or use different parameter types",
--                                      member.GetSignatureForError ());
--                              return false;
--                      }
--
--                      return true;
--              }
--      }
  }
index 42ad264bb9ca25355b3a3ff47be62b073e8e2eac,ffb4eeaedf5c5103f911e50b4c3aa72f61c768c4..cecef2b03efc48a9bff0ab7bb19ec80e9681aaf1
      </Compile>
      <Compile Include="location.cs">
      </Compile>
++    <Compile Include="membercache.cs" />
      <Compile Include="method.cs" />
      <Compile Include="modifiers.cs">
      </Compile>
      </Compile>
      <Compile Include="linq.cs" />
      <Compile Include="field.cs" />
++    <Compile Include="typespec.cs" />
    </ItemGroup>
    <ItemGroup>
      <Folder Include="Properties\" />
index 9ddbb8e4251e9f27b869b65fc19cea49de01dc14,de7bbdc86f19cc354297e22d034240ab2f15f457..17c9e9913d4d1ff6ff0e65eb81369b5c147d16f6
@@@ -30,6 -30,6 +30,7 @@@ lambda.c
  linq.cs
  literal.cs
  location.cs
++membercache.cs
  method.cs
  modifiers.cs
  namespace.cs
@@@ -43,6 -42,6 +44,7 @@@ roottypes.c
  statement.cs
  support.cs
  typemanager.cs
++typespec.cs
  symbolwriter.cs
  ../class/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs
  ../class/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs
diff --cc mcs/mcs/enum.cs
index 82229d8b4bacbab67885dd5a28e4ab3df5838660,82229d8b4bacbab67885dd5a28e4ab3df5838660..716b506a95b001a80dd1a0aebe4008f6e2bb0447
@@@ -230,4 -230,4 +230,15 @@@ namespace Mono.CSharp 
                        }
                }
        }
++
++      public class EnumSpec : TypeSpec
++      {
++              public EnumSpec (MemberKind kind, ITypeDefinition definition, TypeSpec underlyingType, Type info, string name, Modifiers modifiers)
++                      : base (kind, definition, info, name, modifiers)
++              {
++                      this.UnderlyingType = underlyingType;
++              }
++
++              public TypeSpec UnderlyingType { get; private set; }
++      }
  }
index 9b8679aff4073df4762ae3dd30f7abf693ed0188,9b8679aff4073df4762ae3dd30f7abf693ed0188..c6e490b8af5c0af9f747c140e08c2b166b923c7f
@@@ -235,7 -235,7 +235,7 @@@ namespace Mono.CShar
                FieldInfo info;
  
                public FieldSpec (IMemberDefinition definition, FieldInfo info, Modifiers modifiers)
--                      : base (definition, info.Name, modifiers)
++                      : base (MemberKind.Field, definition, info.Name, modifiers)
                {
                        this.info = info;
                }
index 8cd3fe8a38f3552bab7f11b1324bfde55655e09a,53578f025f9788f118db866f9c2e77130970ab50..150d29efb32cc9ebc148fe701b0bb6e5c5a68c45
@@@ -31,6 -31,6 +31,7 @@@ lambda.c
  linq.cs
  literal.cs
  location.cs
++membercache.cs
  method.cs
  modifiers.cs
  namespace.cs
@@@ -44,6 -43,6 +45,7 @@@ roottypes.c
  statement.cs
  support.cs
  typemanager.cs
++typespec.cs
  symbolwriter.cs
  ../class/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs
  ../class/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs
index 12d14f1d361a7009e85adb3a7558fc178bc1d7ad,e5c990d47bda4db4a395a6071103dfc3798fe0a4..05ed3b87c13c6a57df56f49965707b5a3d783121
@@@ -5,7 -5,7 +5,7 @@@
  //
  // Dual licensed under the terms of the MIT X11 or GNU GPL
  //
--// Copyright 2009 Novell, Inc
++// Copyright 2009, 2010 Novell, Inc
  //
  
  using System;
@@@ -152,17 -152,10 +152,98 @@@ namespace Mono.CShar
  
                        // TODO MemberCache: Use AParametersCollection p = ParametersImported.Create (mb);
                        AParametersCollection p = TypeManager.GetParameterData (mb);
--                      MethodSpec ms = new MethodSpec (definition, mb, p, mod);
++
++                      MemberKind kind;
++                      if (mb.IsConstructor) {
++                              kind = MemberKind.Constructor;
++                      } else {
++                              //
++                              // Detect operators and destructors
++                              //
++                              string name = mb.Name;
++                              kind = MemberKind.Method;
++                              if (!mb.DeclaringType.IsInterface && name.Length > 6) {
++                                      if ((mod & Modifiers.STATIC) != 0 && name[2] == '_' && name[1] == 'p' && name[0] == 'o') {
++                                              var op_type = Operator.GetType (name);
++                                              if (op_type.HasValue) {
++                                                      kind = MemberKind.Operator;
++                                              }
++                                      } else if (p.IsEmpty && (mod & Modifiers.STATIC) == 0 && name == Destructor.MetadataName) {
++                                              kind = MemberKind.Destructor;
++                                      }
++                              }
++                      }
++                              
++                      MethodSpec ms = new MethodSpec (kind, definition, mb, p, mod);
                        return ms;
                }
  
-                       return new PropertySpec (definition, pi, mod);
 +              public static PropertySpec CreateProperty (PropertyInfo pi)
 +              {
 +                      var definition = new ImportedMemberDefinition (pi);
 +                      var mod = Modifiers.PRIVATE;    // TODO: modifiers
++                      return new PropertySpec (MemberKind.Property | MemberKind.Indexer, definition, pi, mod);
++              }
++
++              static TypeSpec CreateType (Type type)
++              {
++                      Modifiers mod = 0;
++                      var ma = type.Attributes;
++                      switch (ma & TypeAttributes.VisibilityMask) {
++                              case TypeAttributes.Public:
++                              case TypeAttributes.NestedPublic:
++                                      mod = Modifiers.PUBLIC;
++                                      break;
++                case TypeAttributes.NestedPrivate:
++                                      mod = Modifiers.PRIVATE;
++                                      break;
++                              case TypeAttributes.NestedFamily:
++                                      mod = Modifiers.PROTECTED;
++                                      break;
++                              case TypeAttributes.NestedFamORAssem:
++                                      mod = Modifiers.PROTECTED | Modifiers.INTERNAL;
++                                      break;
++                              default:
++                                      mod = Modifiers.INTERNAL;
++                                      break;
++                      }
++
++                      var type_def = TypeManager.DropGenericTypeArguments (type);
++
++                      MemberKind kind;
++                      if (type_def.IsInterface)
++                              kind = MemberKind.Interface;
++                      else if (type_def.IsEnum)
++                              kind = MemberKind.Enum;
++                      else if (type_def.IsClass) {
++                              if (type_def.BaseType == TypeManager.multicast_delegate_type)
++                                      kind = MemberKind.Delegate;
++                              else
++                                      kind = MemberKind.Class;
++                      } else {
++                              kind = MemberKind.Struct;
++                      }
++
++                      if (type.IsGenericType) {
++                              throw new NotImplementedException ();
++                      }
++
++                      var definition = new ImportedTypeDefinition (type_def);
++                      var spec = new TypeSpec (kind, definition, type, type.Name, mod);
++
++                      // TODO: BaseType for class only?
++
++                      return spec;
++              }
++
++              public static TypeSpec ImportType (Type type)
++              {
++                      if (type.IsDefined (typeof (CompilerGeneratedAttribute), false))
++                              return null;
++
++                      return CreateType (type);
 +              }
 +
                //
                // Decimal constants cannot be encoded in the constant blob, and thus are marked
                // as IsInitOnly ('readonly' in C# parlance).  We get its value from the 
                        return ((MethodInfo) provider).MakeGenericMethod (targs);
                }
        }
++
++      class ImportedTypeDefinition : ImportedMemberDefinition, ITypeDefinition
++      {
++              public ImportedTypeDefinition (Type type)
++                      : base (type)
++              {
++              }
++
++              public void LoadMembers (MemberCache cache)
++              {
++                      throw new NotImplementedException ();
++              }
++      }
  }
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d8a630a4af66f67c102b8dddf1db400c82fd66b3
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1506 @@@
++//
++// membercache.cs: A container for all member lookups
++//
++// Author: Miguel de Icaza (miguel@gnu.org)
++//         Marek Safar (marek.safar@gmail.com)
++//
++// Dual licensed under the terms of the MIT X11 or GNU GPL
++//
++// Copyright 2001 Ximian, Inc (http://www.ximian.com)
++// Copyright 2004-2010 Novell, Inc
++//
++//
++
++using System;
++using System.Text;
++using System.Collections.Generic;
++using System.Globalization;
++using System.Reflection.Emit;
++using System.Reflection;
++
++namespace Mono.CSharp {
++
++      [Flags]
++      public enum MemberKind
++      {
++              Constructor = 1,
++              Event = 1 << 1,
++              Field = 1 << 2,
++              Method = 1 << 3,
++              Property = 1 << 4,
++              Indexer = 1 << 5,
++              Operator = 1 << 6,
++              Destructor      = 1 << 7,
++              //Constant = 1 << 8,
++
++              NestedType      = 1 << 10,
++
++              Class           = 1 << 11,
++              Struct          = 1 << 12,
++              Delegate        = 1 << 13,
++              Enum            = 1 << 14,
++              Interface       = 1 << 15,
++
++              MaskType = Constructor | Event | Field | Method | Property | NestedType | Indexer | Operator | Destructor,
++              All = MaskType
++      }
++
++      [Flags]
++      public enum BindingRestriction
++      {
++              None = 0,
++
++              // Member has to be accessible
++              AccessibleOnly = 1,
++
++              // Inspect only queried type members
++              DeclaredOnly = 1 << 1,
++
++              // Excluded static
++              InstanceOnly = 1 << 2,
++
++              // 
++              NoOverloadableOverrides = 1 << 3
++      }
++/*
++      public struct MemberFilter : IEquatable<MemberCore>
++      {
++              public readonly string Name;
++              public readonly MemberKind Kind;
++              public readonly TypeSpec[] Parameters;
++              public readonly TypeSpec MemberType;
++
++              public MemberFilter (IMethod m)
++              {
++                      Name = m.MethodBuilder.Name;
++                      Kind = MemberKind.Method;
++                      Parameters = m.Parameters.Types;
++                      MemberType = m.ReturnType;
++              }
++
++              public MemberFilter (string name, MemberKind kind)
++              {
++                      Name = name;
++                      Kind = kind;
++                      Parameters = null;
++                      MemberType = null;
++              }
++
++              public MemberFilter (string name, MemberKind kind, TypeSpec[] param, TypeSpec type)
++                      : this (name, kind)
++              {
++                      Name = name;
++                      Kind = kind;
++                      Parameters = param;
++                      MemberType = type;
++              }
++
++              public static MemberFilter Constuctor (TypeSpec[] param)
++              {
++                      return new MemberFilter (System.Reflection.ConstructorInfo.ConstructorName, MemberKind.Constructor, param, null);
++              }
++
++              public static MemberFilter Property (string name, TypeSpec type)
++              {
++                      return new MemberFilter (name, MemberKind.Property, null, type);
++              }
++
++              public static MemberFilter Field (string name, TypeSpec type)
++              {
++                      return new MemberFilter (name, MemberKind.Field, null, type);
++              }
++
++              public static MemberFilter Method (string name, TypeSpec[] param, TypeSpec type)
++              {
++                      return new MemberFilter (name, MemberKind.Method, param, type);
++              }
++
++              #region IEquatable<MemberCore> Members
++
++              public bool Equals (MemberCore other)
++              {
++                      // Is the member of the correct type ?
++                      if ((other.MemberKind & Kind & MemberKind.MaskType) == 0)
++                              return false;
++
++                      if (Parameters != null) {
++                              if (other is IParametersMember) {
++                                      AParametersCollection other_param = ((IParametersMember) other).Parameters;
++                                      if (TypeSpecArrayComparer.Default.Equals (Parameters, other_param.Types))
++                                              return true;
++                              }
++
++                              return false;
++                      }
++
++                      if (MemberType != null) {
++                              //throw new NotImplementedException ();
++                      }
++
++                      return true;
++              }
++
++              #endregion
++      }
++*/ 
++      /// <summary>
++      ///   This is a readonly list of MemberInfo's.      
++      /// </summary>
++      public class MemberList : IList<MemberInfo> {
++              public readonly IList<MemberInfo> List;
++              int count;
++
++              /// <summary>
++              ///   Create a new MemberList from the given IList.
++              /// </summary>
++              public MemberList (IList<MemberInfo> list)
++              {
++                      if (list != null)
++                              this.List = list;
++                      else
++                              this.List = new List<MemberInfo> ();
++                      count = List.Count;
++              }
++
++              /// <summary>
++              ///   Concatenate the ILists `first' and `second' to a new MemberList.
++              /// </summary>
++              public MemberList (IList<MemberInfo> first, IList<MemberInfo> second)
++              {
++                      var list = new List<MemberInfo> ();
++                      list.AddRange (first);
++                      list.AddRange (second);
++                      count = list.Count;
++                      List = list;
++              }
++
++              public static readonly MemberList Empty = new MemberList (Array.AsReadOnly (new MemberInfo[0]));
++
++              /// <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 void CopyTo (MemberInfo[] array, int index)
++              {
++                      List.CopyTo (array, index);
++              }
++
++              // IEnumerable
++
++              public IEnumerator<MemberInfo> GetEnumerator ()
++              {
++                      return List.GetEnumerator ();
++              }
++
++              System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
++              {
++                      return List.GetEnumerator ();
++              }
++
++              // IList
++
++              public bool IsFixedSize {
++                      get {
++                              return true;
++                      }
++              }
++
++              public bool IsReadOnly {
++                      get {
++                              return true;
++                      }
++              }
++
++              MemberInfo IList<MemberInfo>.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 void Add (MemberInfo value)
++              {
++                      throw new NotSupportedException ();
++              }
++
++              public void Clear ()
++              {
++                      throw new NotSupportedException ();
++              }
++
++              public bool Contains (MemberInfo value)
++              {
++                      return List.Contains (value);
++              }
++
++              public int IndexOf (MemberInfo value)
++              {
++                      return List.IndexOf (value);
++              }
++
++              public void Insert (int index, MemberInfo value)
++              {
++                      throw new NotSupportedException ();
++              }
++
++              public bool Remove (MemberInfo 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 base 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 base class.
++              /// </summary>
++              MemberCache BaseCache {
++                      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>
++      ///   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 Dictionary<string, List<CacheEntry>> member_hash;
++              protected Dictionary<string, List<CacheEntry>> method_hash;
++
++              Dictionary<string, object> locase_table;
++
++              static List<MethodInfo> overrides = new List<MethodInfo> ();
++
++              /// <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 base class (we have a base class unless we're
++                      // TypeManager.object_type), we deep-copy its MemberCache here.
++                      if (Container.BaseCache != null)
++                              member_hash = SetupCache (Container.BaseCache);
++                      else
++                              member_hash = new Dictionary<string, List<CacheEntry>> ();
++
++                      // 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.IsGenericType && (type.GetGenericTypeDefinition () is TypeBuilder)) &&
++                          !TypeManager.IsGenericType (type) && !TypeManager.IsGenericParameter (type) &&
++                          (Container.BaseCache == null || Container.BaseCache.method_hash != null)) {
++                                      method_hash = new Dictionary<string, List<CacheEntry>> ();
++                                      AddMethods (type);
++                      }
++
++                      // Add all members from the current class.
++                      AddMembers (Container);
++
++                      Timer.StopTimer (TimerType.CacheInit);
++              }
++
++              public MemberCache (Type baseType, IMemberContainer container)
++              {
++                      this.Container = container;
++                      if (baseType == null)
++                              this.member_hash = new Dictionary<string, List<CacheEntry>> ();
++                      else
++                              this.member_hash = SetupCache (TypeManager.LookupMemberCache (baseType));
++              }
++
++              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 Dictionary<string, List<CacheEntry>> ();
++                      if (ifaces == null)
++                              return;
++
++                      foreach (Type itype in ifaces)
++                              AddCacheContents (TypeManager.LookupMemberCache (itype));
++              }
++
++              public MemberCache (IMemberContainer container, Type base_class, Type[] ifaces)
++              {
++                      this.Container = container;
++
++                      // If we have a base class (we have a base class unless we're
++                      // TypeManager.object_type), we deep-copy its MemberCache here.
++                      if (Container.BaseCache != null)
++                              member_hash = SetupCache (Container.BaseCache);
++                      else
++                              member_hash = new Dictionary<string, List<CacheEntry>> ();
++
++                      if (base_class != null)
++                              AddCacheContents (TypeManager.LookupMemberCache (base_class));
++                      if (ifaces != null) {
++                              foreach (Type itype in ifaces) {
++                                      MemberCache cache = TypeManager.LookupMemberCache (itype);
++                                      if (cache != null)
++                                              AddCacheContents (cache);
++                              }
++                      }
++              }
++
++              /// <summary>
++              ///   Bootstrap this member cache by doing a deep-copy of our base.
++              /// </summary>
++              static Dictionary<string, List<CacheEntry>> SetupCache (MemberCache base_class)
++              {
++                      if (base_class == null)
++                              return new Dictionary<string, List<CacheEntry>> ();
++
++                      var hash = new Dictionary<string, List<CacheEntry>> (base_class.member_hash.Count);
++                      var it = base_class.member_hash.GetEnumerator ();
++                      while (it.MoveNext ()) {
++                              hash.Add (it.Current.Key, new List<CacheEntry> (it.Current.Value));
++                      }
++                                
++                      return hash;
++              }
++              
++              //
++              // Converts ModFlags to BindingFlags
++              //
++              static BindingFlags GetBindingFlags (Modifiers modifiers)
++              {
++                      BindingFlags bf;
++                      if ((modifiers & Modifiers.STATIC) != 0)
++                              bf = BindingFlags.Static;
++                      else
++                              bf = BindingFlags.Instance;
++
++                      if ((modifiers & Modifiers.PRIVATE) != 0)
++                              bf |= BindingFlags.NonPublic;
++                      else
++                              bf |= BindingFlags.Public;
++
++                      return bf;
++              }               
++
++              /// <summary>
++              ///   Add the contents of `cache' to the member_hash.
++              /// </summary>
++              void AddCacheContents (MemberCache cache)
++              {
++                      var it = cache.member_hash.GetEnumerator ();
++                      while (it.MoveNext ()) {
++                              List<CacheEntry> list;
++                              if (!member_hash.TryGetValue (it.Current.Key, out list))
++                                      member_hash [it.Current.Key] = list = new List<CacheEntry> ();
++
++                              var entries = it.Current.Value;
++                              for (int i = entries.Count-1; i >= 0; i--) {
++                                      var entry = 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);
++              }
++
++              public void AddMember (MemberInfo mi, MemberCore mc)
++              {
++                      AddMember (mi.MemberType, GetBindingFlags (mc.ModFlags), Container, mi.Name, mi);
++              }
++
++              public void AddGenericMember (MemberInfo mi, InterfaceMemberBase mc)
++              {
++                      AddMember (mi.MemberType, GetBindingFlags (mc.ModFlags), Container,
++                              MemberName.MakeName (mc.GetFullName (mc.MemberName), mc.MemberName.TypeArguments), mi);
++              }
++
++              public void AddNestedType (DeclSpace type)
++              {
++                      AddMember (MemberTypes.NestedType, GetBindingFlags (type.ModFlags), (IMemberContainer) type.Parent,
++                              type.TypeBuilder.Name, type.TypeBuilder);
++              }
++
++              public void AddInterface (MemberCache baseCache)
++              {
++                      if (baseCache.member_hash.Count > 0)
++                              AddCacheContents (baseCache);
++              }
++
++              void AddMember (MemberTypes mt, BindingFlags bf, IMemberContainer container,
++                              string name, MemberInfo member)
++              {
++                      // We use a name-based hash table of ArrayList's.
++                      List<CacheEntry> list;
++                      if (!member_hash.TryGetValue (name, out list)) {
++                              list = new List<CacheEntry> (1);
++                              member_hash.Add (name, list);
++                      }
++
++                      // When this method is called for the current class, the list will
++                      // already contain all inherited members from our base 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 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;
++
++                              AddMember (mt, bf, container, name, member);
++
++                              if (member is MethodInfo) {
++                                      string gname = TypeManager.GetMethodName ((MethodInfo) member);
++                                      if (gname != name)
++                                              AddMember (mt, bf, container, gname, member);
++                              }
++                      }
++              }
++
++              /// <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)
++              {
++                      MethodBase [] 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.
++                              List<CacheEntry> list;
++                              if (!method_hash.TryGetValue (name, out list)) {
++                                      list = new List<CacheEntry> (1);
++                                      method_hash.Add (name, list);
++                              }
++
++                              MethodInfo curr = (MethodInfo) member;
++                              while (curr.IsVirtual && (curr.Attributes & MethodAttributes.NewSlot) == 0) {
++                                      MethodInfo base_method = curr.GetBaseDefinition ();
++
++                                      if (base_method == curr)
++                                              // Not every virtual function needs to have a NewSlot flag.
++                                              break;
++
++                                      overrides.Add (curr);
++                                      list.Add (new CacheEntry (null, base_method, MemberTypes.Method, bf));
++                                      curr = base_method;
++                              }
++
++                              if (overrides.Count > 0) {
++                                      for (int i = 0; i < overrides.Count; ++i)
++                                              TypeManager.RegisterOverride ((MethodBase) overrides [i], curr);
++                                      overrides.Clear ();
++                              }
++
++                              // 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]
++              public 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,
++
++                      NotExtensionMethod      = 0x800,
++
++                      MaskType        = Constructor|Event|Field|Method|Property|NestedType
++              }
++
++              public class CacheEntry {
++                      public readonly IMemberContainer Container;
++                      public 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 (IList<MemberInfo> 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>
++              List<MemberInfo> global = new List<MemberInfo> ();
++              bool using_global;
++              
++              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);
++
++                      List<CacheEntry> 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))
++                              method_hash.TryGetValue (name, out applicable);
++                      else
++                              member_hash.TryGetValue (name, out applicable);
++
++                      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;
++
++                      bool do_interface_search = current.IsInterface;
++
++                      // `applicable' is a list of all members with the given member name `name'
++                      // in the current class and all its base 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 base).
++
++                      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)
++                                              break;
++
++                                      if (!do_interface_search && 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;
++                                      }
++                                      
++                                      // Because interfaces support multiple inheritance we have to be sure that
++                                      // base member is from same interface, so only top level member will be returned
++                                      if (do_interface_search && global.Count > 0) {
++                                              bool member_already_exists = false;
++
++                                              foreach (MemberInfo mi in global) {
++                                                      if (mi is MethodBase)
++                                                              continue;
++
++                                                      if (IsInterfaceBaseInterface (TypeManager.GetInterfaces (mi.DeclaringType), entry.Member.DeclaringType)) {
++                                                              member_already_exists = true;
++                                                              break;
++                                                      }
++                                              }
++                                              if (member_already_exists)
++                                                      continue;
++                                      }
++
++                                      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;
++              }
++
++              /// <summary>
++              /// Returns true if iterface exists in any base interfaces (ifaces)
++              /// </summary>
++              static bool IsInterfaceBaseInterface (Type[] ifaces, Type ifaceToFind)
++              {
++                      foreach (Type iface in ifaces) {
++                              if (iface == ifaceToFind)
++                                      return true;
++
++                              Type[] base_ifaces = TypeManager.GetInterfaces (iface);
++                              if (base_ifaces.Length > 0 && IsInterfaceBaseInterface (base_ifaces, ifaceToFind))
++                                      return true;
++                      }
++                      return false;
++              }
++              
++              // find the nested type @name in @this.
++              public Type FindNestedType (string name)
++              {
++                      List<CacheEntry> applicable;
++                      if (!member_hash.TryGetValue (name, out applicable))
++                              return null;
++                      
++                      for (int i = applicable.Count-1; i >= 0; i--) {
++                              CacheEntry entry = applicable [i];
++                              if ((entry.EntryType & EntryType.NestedType & EntryType.MaskType) != 0)
++                                      return (Type) entry.Member;
++                      }
++                      
++                      return null;
++              }
++
++              public MemberInfo FindBaseEvent (Type invocation_type, string name)
++              {
++                      List<CacheEntry> applicable;
++                      if (!member_hash.TryGetValue (name, out applicable))
++                              return null;
++
++                      //
++                      // Walk the chain of events, starting from the top.
++                      //
++                      for (int i = applicable.Count - 1; i >= 0; i--) 
++                      {
++                              CacheEntry entry = applicable [i];
++                              if ((entry.EntryType & EntryType.Event) == 0)
++                                      continue;
++                              
++                              EventInfo ei = (EventInfo)entry.Member;
++                              return ei.GetAddMethod (true);
++                      }
++
++                      return null;
++              }
++
++              //
++              // Looks for extension methods with defined name and extension type
++              //
++              public List<MethodSpec> FindExtensionMethods (Assembly thisAssembly, Type extensionType, string name, bool publicOnly)
++              {
++                      List<CacheEntry> entries;
++                      if (method_hash != null)
++                              method_hash.TryGetValue (name, out entries);
++                      else {
++                              member_hash.TryGetValue (name, out entries);
++                      }
++
++                      if (entries == null)
++                              return null;
++
++                      EntryType entry_type = EntryType.Static | EntryType.Method | EntryType.NotExtensionMethod;
++                      EntryType found_entry_type = entry_type & ~EntryType.NotExtensionMethod;
++
++                      List<MethodSpec> candidates = null;
++                      foreach (CacheEntry entry in entries) {
++                              if ((entry.EntryType & entry_type) == found_entry_type) {
++                                      MethodBase mb = (MethodBase)entry.Member;
++
++                                      // Simple accessibility check
++                                      if ((entry.EntryType & EntryType.Public) == 0 && publicOnly) {
++                                              MethodAttributes ma = mb.Attributes & MethodAttributes.MemberAccessMask;
++                                              if (ma != MethodAttributes.Assembly && ma != MethodAttributes.FamORAssem)
++                                                      continue;
++                                              
++                                              if (!TypeManager.IsThisOrFriendAssembly (thisAssembly, mb.DeclaringType.Assembly))
++                                                      continue;
++                                      }
++
++                                      IMethodData md = TypeManager.GetMethod (mb);
++                                      AParametersCollection pd = md == null ?
++                                              TypeManager.GetParameterData (mb) : md.ParameterInfo;
++
++                                      Type ex_type = pd.ExtensionMethodType;
++                                      if (ex_type == null) {
++                                              entry.EntryType |= EntryType.NotExtensionMethod;
++                                              continue;
++                                      }
++
++                                      if (candidates == null)
++                                              candidates = new List<MethodSpec> (2);
++                                      candidates.Add (Import.CreateMethod (mb));
++                              }
++                      }
++
++                      return candidates;
++              }
++              
++              //
++              // This finds the method or property for us to override. invocation_type is the type where
++              // the override is going to be declared, name is the name of the method/property, and
++              // param_types 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 invocation_type, string name, AParametersCollection parameters, GenericMethod generic_method, bool is_property)
++              {
++                      List<CacheEntry> applicable;
++                      if (method_hash != null && !is_property)
++                              method_hash.TryGetValue (name, out applicable);
++                      else
++                              member_hash.TryGetValue (name, out applicable);
++                      
++                      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 = applicable [i];
++                              
++                              if ((entry.EntryType & (is_property ? (EntryType.Property | EntryType.Field) : EntryType.Method)) == 0)
++                                      continue;
++
++                              PropertyInfo pi = null;
++                              MethodInfo mi = null;
++                              FieldInfo fi = null;
++                              AParametersCollection cmp_attrs;
++                              
++                              if (is_property) {
++                                      if ((entry.EntryType & EntryType.Field) != 0) {
++                                              fi = (FieldInfo)entry.Member;
++                                              cmp_attrs = ParametersCompiled.EmptyReadOnlyParameters;
++                                      } else {
++                                              pi = (PropertyInfo) entry.Member;
++                                              cmp_attrs = TypeManager.GetParameterData (pi);
++                                      }
++                              } else {
++                                      mi = (MethodInfo) entry.Member;
++                                      cmp_attrs = TypeManager.GetParameterData (mi);
++                              }
++
++                              if (fi != null) {
++                                      // TODO: Almost duplicate !
++                                      // Check visibility
++                                      switch (fi.Attributes & FieldAttributes.FieldAccessMask) {
++                                      case FieldAttributes.PrivateScope:
++                                              continue;
++                                      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 (!invocation_type.Equals (entry.Container.Type) &&
++                                                  !TypeManager.IsNestedChildOf (invocation_type, entry.Container.Type))
++                                                      continue;
++                                              break;
++                                      case FieldAttributes.FamANDAssem:
++                                      case FieldAttributes.Assembly:
++                                              //
++                                              // Check for assembly methods
++                                              //
++                                              if (fi.DeclaringType.Assembly != CodeGen.Assembly.Builder)
++                                                      continue;
++                                              break;
++                                      }
++                                      return entry.Member;
++                              }
++
++                              //
++                              // Check the arguments
++                              //
++                              if (cmp_attrs.Count != parameters.Count)
++                                      continue;
++      
++                              int j;
++                              for (j = 0; j < cmp_attrs.Count; ++j) {
++                                      //
++                                      // LAMESPEC: No idea why `params' modifier is ignored
++                                      //
++                                      if ((parameters.FixedParameters [j].ModFlags & ~Parameter.Modifier.PARAMS) != 
++                                              (cmp_attrs.FixedParameters [j].ModFlags & ~Parameter.Modifier.PARAMS))
++                                              break;
++
++                                      if (!TypeManager.IsEqual (parameters.Types [j], cmp_attrs.Types [j]))
++                                              break;
++                              }
++
++                              if (j < cmp_attrs.Count)
++                                      continue;
++
++                              //
++                              // check generic arguments for methods
++                              //
++                              if (mi != null) {
++                                      Type [] cmpGenArgs = TypeManager.GetGenericArguments (mi);
++                                      if (generic_method == null && cmpGenArgs != null && cmpGenArgs.Length != 0)
++                                              continue;
++                                      if (generic_method != null && cmpGenArgs != null && cmpGenArgs.Length != generic_method.TypeParameters.Length)
++                                              continue;
++                              }
++
++                              //
++                              // 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.PrivateScope:
++                                      continue;
++                              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 (!invocation_type.Equals (entry.Container.Type) &&
++                                          !TypeManager.IsNestedChildOf (invocation_type, entry.Container.Type))
++                                              continue;
++                                      break;
++                              case MethodAttributes.FamANDAssem:
++                              case MethodAttributes.Assembly:
++                                      //
++                                      // Check for assembly methods
++                                      //
++                                      if (!TypeManager.IsThisOrFriendAssembly (invocation_type.Assembly, mi.DeclaringType.Assembly))
++                                              continue;
++                                      break;
++                              }
++                              return entry.Member;
++                      }
++                      
++                      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)
++              {
++                      List<CacheEntry> applicable = null;
++ 
++                      if (method_hash != null)
++                              method_hash.TryGetValue (name, out applicable);
++ 
++                      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;
++
++                      if (member_hash.TryGetValue (name, out applicable)) {
++                              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) {
++                                                              AParametersCollection arg_types = TypeManager.GetParameterData ((PropertyInfo)entry.Member);
++                                                              if (arg_types.Count > 0)
++                                                                      continue;
++                                                      }
++                                              }
++                                              return entry.Member;
++                                      }
++                              }
++                      }
++                      return null;
++              }
++
++
++              /// <summary>
++              /// Builds low-case table for CLS Compliance test
++              /// </summary>
++              public Dictionary<string, object> GetPublicMembers ()
++              {
++                      if (locase_table != null)
++                              return locase_table;
++
++                      locase_table = new Dictionary<string, object> ();
++                      foreach (var entry in member_hash) {
++                              var members = entry.Value;
++                              for (int ii = 0; ii < members.Count; ++ii) {
++                                      CacheEntry member_entry = 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 IDictionary<string, List<CacheEntry>> 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>
++              /// 
++              // TODO: refactor as method is always 'this'
++              public static void VerifyClsParameterConflict (IList<CacheEntry> al, MethodCore method, MemberInfo this_builder, Report Report)
++              {
++                      EntryType tested_type = (method is Constructor ? EntryType.Constructor : EntryType.Method) | EntryType.Public;
++ 
++                      for (int i = 0; i < al.Count; ++i) {
++                              var entry = 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;
++                              AttributeTester.Result result = AttributeTester.AreOverloadedMethodParamsClsCompliant (
++                                      method.Parameters, TypeManager.GetParameterData (method_to_compare));
++
++                              if (result == AttributeTester.Result.Ok)
++                                      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.IsClsComplianceRequired ())
++                                      continue;
++              
++                              Report.SymbolRelatedToPreviousError (entry.Member);
++                              switch (result) {
++                              case AttributeTester.Result.RefOutArrayError:
++                                      Report.Warning (3006, 1, method.Location,
++                                                      "Overloaded method `{0}' differing only in ref or out, or in array rank, is not CLS-compliant",
++                                                      method.GetSignatureForError ());
++                                      continue;
++                              case AttributeTester.Result.ArrayArrayError:
++                                      Report.Warning (3007, 1, method.Location,
++                                                      "Overloaded method `{0}' differing only by unnamed array types is not CLS-compliant",
++                                                      method.GetSignatureForError ());
++                                      continue;
++                              }
++
++                              throw new NotImplementedException (result.ToString ());
++                      }
++              }
++
++              public bool CheckExistingMembersOverloads (MemberCore member, string name, ParametersCompiled parameters, Report Report)
++              {
++                      List<CacheEntry> entries;
++                      if (!member_hash.TryGetValue (name, out entries))
++                              return true;
++
++                      int method_param_count = parameters.Count;
++                      for (int i = entries.Count - 1; i >= 0; --i) {
++                              CacheEntry ce = (CacheEntry) entries [i];
++
++                              if (ce.Container != member.Parent.PartialContainer)
++                                      return true;
++
++                              Type [] p_types;
++                              AParametersCollection pd;
++                              if ((ce.EntryType & EntryType.Property) != 0) {
++                                      pd = TypeManager.GetParameterData ((PropertyInfo) ce.Member);
++                                      p_types = pd.Types;
++                              } else {
++                                      MethodBase mb = (MethodBase) ce.Member;
++              
++                                      // TODO: This is more like a hack, because we are adding generic methods
++                                      // twice with and without arity name
++                                      if (TypeManager.IsGenericMethod (mb) && !member.MemberName.IsGeneric)
++                                              continue;
++
++                                      pd = TypeManager.GetParameterData (mb);
++                                      p_types = pd.Types;
++                              }
++
++                              if (p_types.Length != method_param_count)
++                                      continue;
++
++                              if (method_param_count > 0) {
++                                      int ii = method_param_count - 1;
++                                      Type type_a, type_b;
++                                      do {
++                                              type_a = parameters.Types [ii];
++                                              type_b = p_types [ii];
++
++                                              if (TypeManager.IsGenericParameter (type_a) && type_a.DeclaringMethod != null)
++                                                      type_a = typeof (TypeParameter);
++
++                                              if (TypeManager.IsGenericParameter (type_b) && type_b.DeclaringMethod != null)
++                                                      type_b = typeof (TypeParameter);
++
++                                              if ((pd.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF) !=
++                                                      (parameters.FixedParameters [ii].ModFlags & Parameter.Modifier.ISBYREF))
++                                                      break;
++
++                                      } while (TypeManager.IsEqual (type_a, type_b) && ii-- != 0);
++
++                                      if (ii >= 0)
++                                              continue;
++
++                                      //
++                                      // Operators can differ in return type only
++                                      //
++                                      if (member is Operator) {
++                                              Operator op = TypeManager.GetMethod ((MethodBase) ce.Member) as Operator;
++                                              if (op != null && op.ReturnType != ((Operator) member).ReturnType)
++                                                      continue;
++                                      }
++
++                                      //
++                                      // Report difference in parameter modifiers only
++                                      //
++                                      if (pd != null && member is MethodCore) {
++                                              ii = method_param_count;
++                                              while (ii-- != 0 && parameters.FixedParameters [ii].ModFlags == pd.FixedParameters [ii].ModFlags &&
++                                                      parameters.ExtensionMethodType == pd.ExtensionMethodType);
++
++                                              if (ii >= 0) {
++                                                      MethodCore mc = TypeManager.GetMethod ((MethodBase) ce.Member) as MethodCore;
++                                                      Report.SymbolRelatedToPreviousError (ce.Member);
++                                                      if ((member.ModFlags & Modifiers.PARTIAL) != 0 && (mc.ModFlags & Modifiers.PARTIAL) != 0) {
++                                                              if (parameters.HasParams || pd.HasParams) {
++                                                                      Report.Error (758, member.Location,
++                                                                              "A partial method declaration and partial method implementation cannot differ on use of `params' modifier");
++                                                              } else {
++                                                                      Report.Error (755, member.Location,
++                                                                              "A partial method declaration and partial method implementation must be both an extension method or neither");
++                                                              }
++                                                      } else {
++                                                              if (member is Constructor) {
++                                                                      Report.Error (851, member.Location,
++                                                                              "Overloaded contructor `{0}' cannot differ on use of parameter modifiers only",
++                                                                              member.GetSignatureForError ());
++                                                              } else {
++                                                                      Report.Error (663, member.Location,
++                                                                              "Overloaded method `{0}' cannot differ on use of parameter modifiers only",
++                                                                              member.GetSignatureForError ());
++                                                              }
++                                                      }
++                                                      return false;
++                                              }
++                                      }
++                              }
++
++                              if ((ce.EntryType & EntryType.Method) != 0) {
++                                      Method method_a = member as Method;
++                                      Method method_b = TypeManager.GetMethod ((MethodBase) ce.Member) as Method;
++                                      if (method_a != null && method_b != null && (method_a.ModFlags & method_b.ModFlags & Modifiers.PARTIAL) != 0) {
++                                              const Modifiers partial_modifiers = Modifiers.STATIC | Modifiers.UNSAFE;
++                                              if (method_a.IsPartialDefinition == method_b.IsPartialImplementation) {
++                                                      if ((method_a.ModFlags & partial_modifiers) == (method_b.ModFlags & partial_modifiers) ||
++                                                              method_a.Parent.IsUnsafe && method_b.Parent.IsUnsafe) {
++                                                              if (method_a.IsPartialImplementation) {
++                                                                      method_a.SetPartialDefinition (method_b);
++                                                                      entries.RemoveAt (i);
++                                                              } else {
++                                                                      method_b.SetPartialDefinition (method_a);
++                                                                      method_a.caching_flags |= MemberCore.Flags.PartialDefinitionExists;
++                                                              }
++                                                              continue;
++                                                      }
++
++                                                      if ((method_a.ModFlags & Modifiers.STATIC) != (method_b.ModFlags & Modifiers.STATIC)) {
++                                                              Report.SymbolRelatedToPreviousError (ce.Member);
++                                                              Report.Error (763, member.Location,
++                                                                      "A partial method declaration and partial method implementation must be both `static' or neither");
++                                                      }
++
++                                                      Report.SymbolRelatedToPreviousError (ce.Member);
++                                                      Report.Error (764, member.Location,
++                                                              "A partial method declaration and partial method implementation must be both `unsafe' or neither");
++                                                      return false;
++                                              }
++
++                                              Report.SymbolRelatedToPreviousError (ce.Member);
++                                              if (method_a.IsPartialDefinition) {
++                                                      Report.Error (756, member.Location, "A partial method `{0}' declaration is already defined",
++                                                              member.GetSignatureForError ());
++                                              } else {
++                                                      Report.Error (757, member.Location, "A partial method `{0}' implementation is already defined",
++                                                              member.GetSignatureForError ());
++                                              }
++
++                                              return false;
++                                      }
++
++                                      Report.SymbolRelatedToPreviousError (ce.Member);
++                                      IMethodData duplicate_member = TypeManager.GetMethod ((MethodBase) ce.Member);
++                                      if (member is Operator && duplicate_member is Operator) {
++                                              Report.Error (557, member.Location, "Duplicate user-defined conversion in type `{0}'",
++                                                      member.Parent.GetSignatureForError ());
++                                              return false;
++                                      }
++
++                                      bool is_reserved_a = member is AbstractPropertyEventMethod || member is Operator;
++                                      bool is_reserved_b = duplicate_member is AbstractPropertyEventMethod || duplicate_member is Operator;
++
++                                      if (is_reserved_a || is_reserved_b) {
++                                              Report.Error (82, member.Location, "A member `{0}' is already reserved",
++                                                      is_reserved_a ?
++                                                      TypeManager.GetFullNameSignature (ce.Member) :
++                                                      member.GetSignatureForError ());
++                                              return false;
++                                      }
++                              } else {
++                                      Report.SymbolRelatedToPreviousError (ce.Member);
++                              }
++                              
++                              Report.Error (111, member.Location,
++                                      "A member `{0}' is already defined. Rename this member or use different parameter types",
++                                      member.GetSignatureForError ());
++                              return false;
++                      }
++
++                      return true;
++              }
++      }
++}
index 1ed1913a85b43757d784d7976494230f9ebf63ea,1ed1913a85b43757d784d7976494230f9ebf63ea..184fdb8f8ff616d77be26a67b074b6a5f3c4cfa9
@@@ -164,8 -164,8 +164,8 @@@ namespace Mono.CSharp 
                MethodBase metaInfo;
                readonly AParametersCollection parameters;
  
--              public MethodSpec (IMemberDefinition details, MethodBase info, AParametersCollection parameters, Modifiers modifiers)
--                      : base (details, info.Name, modifiers)
++              public MethodSpec (MemberKind kind, IMemberDefinition details, MethodBase info, AParametersCollection parameters, Modifiers modifiers)
++                      : base (kind, details, info.Name, modifiers)
                {
                        this.MetaInfo = info;
                        this.parameters = parameters;
                        // TODO: Does not work on .NET
                        var par = TypeManager.GetParameterData (mb);
  
--                      return new MethodSpec (definition, mb, par, modifiers);
++                      return new MethodSpec (Kind, definition, mb, par, modifiers);
                }
  
                public bool IsAbstract {
                                ModFlags |= Modifiers.DEBUGGER_HIDDEN;
                        }
  
++                      MemberKind kind;
++                      if (this is Operator)
++                              kind = MemberKind.Operator;
++                      else if (this is Destructor)
++                              kind = MemberKind.Destructor;
++                      else
++                              kind = MemberKind.Method;
++
                        if (IsPartialDefinition) {
                                caching_flags &= ~Flags.Excluded_Undetected;
                                caching_flags |= Flags.Excluded;
                                        Parent.MemberCache.AddMember (mb, this);
                                        TypeManager.AddMethod (mb, this);
  
--                                      spec = new MethodSpec (this, mb, Parameters, ModFlags);
++                                      spec = new MethodSpec (kind, this, mb, Parameters, ModFlags);
                                }
  
                                return true;
                                        
                        MethodBuilder = MethodData.MethodBuilder;
  
--                      spec = new MethodSpec (this, MethodBuilder, Parameters, ModFlags);
++                      spec = new MethodSpec (kind, this, MethodBuilder, Parameters, ModFlags);
  
                        if (TypeManager.IsGenericMethod (MethodBuilder))
                                Parent.MemberCache.AddGenericMember (MethodBuilder, this);
                                ca, CallingConventions,
                                Parameters.GetEmitTypes ());
  
--                      spec = new MethodSpec (this, ConstructorBuilder, Parameters, ModFlags);
++                      spec = new MethodSpec (MemberKind.Constructor, this, ConstructorBuilder, Parameters, ModFlags);
  
                        if (Parent.PartialContainer.IsComImport) {
                                if (!IsDefault ()) {
                        return null;
                }
  
++              public static OpType? GetType (string metadata_name)
++              {
++                      for (int i = 0; i < names.Length; ++i) {
++                              if (names[i][1] == metadata_name)
++                                      return (OpType) i;
++                      }
++
++                      return null;
++              }
++
                public OpType GetMatchingOperator ()
                {
                        switch (OperatorType) {
index 800d0d729bae50c4014c632a4f05df6c1e4eebcb,0000000000000000000000000000000000000000..1b8c13aaf6d3bcc0263c224d4f208d51206b0952
mode 100644,000000..100644
--- /dev/null
@@@ -1,1581 -1,0 +1,1581 @@@
-               public PropertySpec (IMemberDefinition definition, PropertyInfo info, Modifiers modifiers)
-                       : base (definition, info.Name, modifiers)
 +//
 +// property.cs: Property based handlers
 +//
 +// Authors: Miguel de Icaza (miguel@gnu.org)
 +//          Martin Baulig (martin@ximian.com)
 +//          Marek Safar (marek.safar@seznam.cz)
 +//
 +// Dual licensed under the terms of the MIT X11 or GNU GPL
 +//
 +// Copyright 2001, 2002, 2003 Ximian, Inc (http://www.ximian.com)
 +// Copyright 2004-2008 Novell, Inc
 +//
 +
 +using System;
 +using System.Collections.Generic;
 +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;
 +
 +#if NET_2_1
 +using XmlElement = System.Object;
 +#else
 +using System.Xml;
 +#endif
 +
 +using Mono.CompilerServices.SymbolWriter;
 +
 +namespace Mono.CSharp
 +{
 +      // It is used as a base class for all property based members
 +      // This includes properties, indexers, and events
 +      public abstract class PropertyBasedMember : InterfaceMemberBase
 +      {
 +              public PropertyBasedMember (DeclSpace parent, GenericMethod generic,
 +                      FullNamedExpression type, Modifiers mod, Modifiers allowed_mod,
 +                      MemberName name, Attributes attrs)
 +                      : base (parent, generic, type, mod, allowed_mod, name, attrs)
 +              {
 +              }
 +
 +              protected override bool VerifyClsCompliance ()
 +              {
 +                      if (!base.VerifyClsCompliance ())
 +                              return false;
 +
 +                      if (!AttributeTester.IsClsCompliant (MemberType)) {
 +                              Report.Warning (3003, 1, Location, "Type of `{0}' is not CLS-compliant",
 +                                      GetSignatureForError ());
 +                      }
 +                      return true;
 +              }
 +
 +      }
 +
 +      //
 +      // `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 Modifiers AllowedModifiers = 
 +                      Modifiers.PUBLIC |
 +                      Modifiers.PROTECTED |
 +                      Modifiers.INTERNAL |
 +                      Modifiers.PRIVATE;
 +              
 +              public ToplevelBlock Block;
 +              public Attributes Attributes;
 +              public Location Location;
 +              public Modifiers ModFlags;
 +              public ParametersCompiled Parameters;
 +              
 +              public Accessor (ToplevelBlock b, Modifiers mod, Attributes attrs, ParametersCompiled p, Location loc)
 +              {
 +                      Block = b;
 +                      Attributes = attrs;
 +                      Location = loc;
 +                      Parameters = p;
 +                      ModFlags = ModifiersExtensions.Check (AllowedModifiers, mod, 0, loc, RootContext.ToplevelTypes.Compiler.Report);
 +              }
 +      }
 +
 +      public class PropertySpec : MemberSpec
 +      {
 +              PropertyInfo info;
 +
++              public PropertySpec (MemberKind kind, IMemberDefinition definition, PropertyInfo info, Modifiers modifiers)
++                      : base (kind, definition, info.Name, modifiers)
 +              {
 +                      this.info = info;
 +              }
 +
 +              public override Type DeclaringType {
 +                      get { return info.DeclaringType; }
 +              }
 +
 +              public PropertyInfo MetaInfo {
 +                      get { return info; }
 +              }
 +
 +              public Type PropertyType {
 +                      get { return info.PropertyType; }
 +              }
 +      }
 +
 +      //
 +      // Properties and Indexers both generate PropertyBuilders, we use this to share 
 +      // their common bits.
 +      //
 +      abstract public class PropertyBase : PropertyBasedMember {
 +
 +              public class GetMethod : PropertyMethod
 +              {
 +                      static string[] attribute_targets = new string [] { "method", "return" };
 +
 +                      public GetMethod (PropertyBase method):
 +                              base (method, "get_")
 +                      {
 +                      }
 +
 +                      public GetMethod (PropertyBase method, Accessor accessor):
 +                              base (method, accessor, "get_")
 +                      {
 +                      }
 +
 +                      public override MethodBuilder Define (DeclSpace parent)
 +                      {
 +                              base.Define (parent);
 +
 +                              if (IsDummy)
 +                                      return null;
 +                              
 +                              method_data = new MethodData (method, ModFlags, flags, this);
 +
 +                              if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
 +                                      return null;
 +
 +                              return method_data.MethodBuilder;
 +                      }
 +
 +                      public override Type ReturnType {
 +                              get {
 +                                      return method.MemberType;
 +                              }
 +                      }
 +
 +                      public override ParametersCompiled ParameterInfo {
 +                              get {
 +                                      return ParametersCompiled.EmptyReadOnlyParameters;
 +                              }
 +                      }
 +
 +                      public override string[] ValidAttributeTargets {
 +                              get {
 +                                      return attribute_targets;
 +                              }
 +                      }
 +              }
 +
 +              public class SetMethod : PropertyMethod {
 +
 +                      static string[] attribute_targets = new string [] { "method", "param", "return" };
 +                      ImplicitParameter param_attr;
 +                      protected ParametersCompiled parameters;
 +
 +                      public SetMethod (PropertyBase method) :
 +                              base (method, "set_")
 +                      {
 +                              parameters = new ParametersCompiled (Compiler,
 +                                      new Parameter (method.type_name, "value", Parameter.Modifier.NONE, null, Location));
 +                      }
 +
 +                      public SetMethod (PropertyBase method, Accessor accessor):
 +                              base (method, accessor, "set_")
 +                      {
 +                              this.parameters = accessor.Parameters;
 +                      }
 +
 +                      protected override void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
 +                      {
 +                              if (a.Target == AttributeTargets.Parameter) {
 +                                      if (param_attr == null)
 +                                              param_attr = new ImplicitParameter (method_data.MethodBuilder);
 +
 +                                      param_attr.ApplyAttributeBuilder (a, cb, pa);
 +                                      return;
 +                              }
 +
 +                              base.ApplyAttributeBuilder (a, cb, pa);
 +                      }
 +
 +                      public override ParametersCompiled ParameterInfo {
 +                          get {
 +                              return parameters;
 +                          }
 +                      }
 +
 +                      public override MethodBuilder Define (DeclSpace parent)
 +                      {
 +                              parameters.Resolve (this);
 +                              
 +                              base.Define (parent);
 +
 +                              if (IsDummy)
 +                                      return null;
 +
 +                              method_data = new MethodData (method, ModFlags, flags, this);
 +
 +                              if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
 +                                      return null;
 +
 +                              return method_data.MethodBuilder;
 +                      }
 +
 +                      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 PropertyBase method;
 +                      protected MethodAttributes flags;
 +
 +                      public PropertyMethod (PropertyBase method, string prefix)
 +                              : base (method, prefix)
 +                      {
 +                              this.method = method;
 +                              this.ModFlags = method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE);                                
 +                      }
 +
 +                      public PropertyMethod (PropertyBase method, Accessor accessor,
 +                                             string prefix)
 +                              : base (method, accessor, prefix)
 +                      {
 +                              this.method = method;
 +                              this.ModFlags = accessor.ModFlags | (method.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE));
 +
 +                              if (accessor.ModFlags != 0 && RootContext.Version == LanguageVersion.ISO_1) {
 +                                      Report.FeatureIsNotAvailable (Location, "access modifiers on properties");
 +                              }
 +                      }
 +
 +                      public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
 +                      {
 +                              if (a.IsInternalMethodImplAttribute) {
 +                                      method.is_external_implementation = true;
 +                              }
 +
 +                              base.ApplyAttributeBuilder (a, cb, pa);
 +                      }
 +
 +                      public override AttributeTargets AttributeTargets {
 +                              get {
 +                                      return AttributeTargets.Method;
 +                              }
 +                      }
 +
 +                      public override bool IsClsComplianceRequired ()
 +                      {
 +                              return method.IsClsComplianceRequired ();
 +                      }
 +
 +                      public virtual MethodBuilder Define (DeclSpace parent)
 +                      {
 +                              CheckForDuplications ();
 +
 +                              if (IsDummy) {
 +                                      if (method.InterfaceType != null && parent.PartialContainer.PendingImplementations != null) {
 +                                              MethodInfo mi = parent.PartialContainer.PendingImplementations.IsInterfaceMethod (
 +                                                      MethodName.Name, method.InterfaceType, new MethodData (method, ModFlags, flags, this));
 +                                              if (mi != null) {
 +                                                      Report.SymbolRelatedToPreviousError (mi);
 +                                                      Report.Error (551, Location, "Explicit interface implementation `{0}' is missing accessor `{1}'",
 +                                                              method.GetSignatureForError (), TypeManager.CSharpSignature (mi, true));
 +                                              }
 +                                      }
 +                                      return null;
 +                              }
 +
 +                              TypeContainer container = parent.PartialContainer;
 +
 +                              //
 +                              // Check for custom access modifier
 +                              //
 +                              if ((ModFlags & Modifiers.AccessibilityMask) == 0) {
 +                                      ModFlags |= method.ModFlags;
 +                                      flags = method.flags;
 +                              } else {
 +                                      if (container.Kind == Kind.Interface)
 +                                              Report.Error (275, Location, "`{0}': accessibility modifiers may not be used on accessors in an interface",
 +                                                      GetSignatureForError ());
 +
 +                                      if ((method.ModFlags & Modifiers.ABSTRACT) != 0 && (ModFlags & Modifiers.PRIVATE) != 0) {
 +                                              Report.Error (442, Location, "`{0}': abstract properties cannot have private accessors", GetSignatureForError ());
 +                                      }
 +
 +                                      CheckModifiers (ModFlags);
 +                                      ModFlags |= (method.ModFlags & (~Modifiers.AccessibilityMask));
 +                                      ModFlags |= Modifiers.PROPERTY_CUSTOM;
 +                                      flags = ModifiersExtensions.MethodAttr (ModFlags);
 +                                      flags |= (method.flags & (~MethodAttributes.MemberAccessMask));
 +                              }
 +
 +                              CheckAbstractAndExtern (block != null);
 +                              CheckProtectedModifier ();
 +
 +                              if (block != null && block.IsIterator)
 +                                      Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags, Compiler);
 +
 +                              return null;
 +                      }
 +
 +                      public bool HasCustomAccessModifier {
 +                              get {
 +                                      return (ModFlags & Modifiers.PROPERTY_CUSTOM) != 0;
 +                              }
 +                      }
 +
 +                      public PropertyBase Property {
 +                              get {
 +                                      return method;
 +                              }
 +                      }
 +
 +                      public override ObsoleteAttribute GetObsoleteAttribute ()
 +                      {
 +                              return method.GetObsoleteAttribute ();
 +                      }
 +
 +                      public override string GetSignatureForError()
 +                      {
 +                              return method.GetSignatureForError () + '.' + prefix.Substring (0, 3);
 +                      }
 +
 +                      void CheckModifiers (Modifiers modflags)
 +                      {
 +                              modflags &= Modifiers.AccessibilityMask;
 +                              Modifiers flags = 0;
 +                              Modifiers mflags = method.ModFlags & Modifiers.AccessibilityMask;
 +
 +                              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,
 +                                              "The accessibility modifier of the `{0}' accessor must be more restrictive than the modifier of the property or indexer `{1}'",
 +                                              GetSignatureForError (), method.GetSignatureForError ());
 +                              }
 +                      }
 +
 +                      protected bool CheckForDuplications ()
 +                      {
 +                              if ((caching_flags & Flags.MethodOverloadsExist) == 0)
 +                                      return true;
 +
 +                              return Parent.MemberCache.CheckExistingMembersOverloads (this, Name, ParameterInfo, Report);
 +                      }
 +              }
 +
 +              public PropertyMethod Get, Set;
 +              public PropertyBuilder PropertyBuilder;
 +              public MethodBuilder GetBuilder, SetBuilder;
 +
 +              protected bool define_set_first = false;
 +
 +              public PropertyBase (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags,
 +                                   Modifiers allowed_mod, MemberName name,
 +                                   Attributes attrs, bool define_set_first)
 +                      : base (parent, null, type, mod_flags, allowed_mod, name, attrs)
 +              {
 +                       this.define_set_first = define_set_first;
 +              }
 +
 +              public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
 +              {
 +                      if (a.HasSecurityAttribute) {
 +                              a.Error_InvalidSecurityParent ();
 +                              return;
 +                      }
 +
 +                      if (a.Type == pa.Dynamic) {
 +                              a.Error_MisusedDynamicAttribute ();
 +                              return;
 +                      }
 +
 +                      PropertyBuilder.SetCustomAttribute (cb);
 +              }
 +
 +              public override AttributeTargets AttributeTargets {
 +                      get {
 +                              return AttributeTargets.Property;
 +                      }
 +              }
 +
 +              protected override void DoMemberTypeDependentChecks ()
 +              {
 +                      base.DoMemberTypeDependentChecks ();
 +
 +                      IsTypePermitted ();
 +#if MS_COMPATIBLE
 +                      if (MemberType.IsGenericParameter)
 +                              return;
 +#endif
 +
 +                      if ((MemberType.Attributes & Class.StaticClassAttribute) == Class.StaticClassAttribute) {
 +                              Report.Error (722, Location, Error722, TypeManager.CSharpName (MemberType));
 +                      }
 +              }
 +
 +              protected override void DoMemberTypeIndependentChecks ()
 +              {
 +                      base.DoMemberTypeIndependentChecks ();
 +
 +                      //
 +                      // Accessors modifiers check
 +                      //
 +                      if ((Get.ModFlags & Modifiers.AccessibilityMask) != 0 &&
 +                              (Set.ModFlags & Modifiers.AccessibilityMask) != 0) {
 +                              Report.Error (274, Location, "`{0}': Cannot specify accessibility modifiers for both accessors of the property or indexer",
 +                                              GetSignatureForError ());
 +                      }
 +
 +                      if ((ModFlags & Modifiers.OVERRIDE) == 0 && 
 +                              (Get.IsDummy && (Set.ModFlags & Modifiers.AccessibilityMask) != 0) ||
 +                              (Set.IsDummy && (Get.ModFlags & Modifiers.AccessibilityMask) != 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 ());
 +                      }
 +              }
 +
 +              bool DefineGet ()
 +              {
 +                      GetBuilder = Get.Define (Parent);
 +                      return (Get.IsDummy) ? true : GetBuilder != null;
 +              }
 +
 +              bool DefineSet (bool define)
 +              {
 +                      if (!define)
 +                              return true;
 +
 +                      SetBuilder = Set.Define (Parent);
 +                      return (Set.IsDummy) ? true : SetBuilder != null;
 +              }
 +
 +              protected bool DefineAccessors ()
 +              {
 +                      return DefineSet (define_set_first) &&
 +                              DefineGet () &&
 +                              DefineSet (!define_set_first);
 +              }
 +
 +              protected abstract PropertyInfo ResolveBaseProperty ();
 +
 +              // TODO: rename to Resolve......
 +              protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
 +              {
 +                      PropertyInfo base_property = ResolveBaseProperty ();
 +                      if (base_property == null)
 +                              return null;
 +
 +                      base_ret_type = base_property.PropertyType;
 +                      MethodInfo get_accessor = base_property.GetGetMethod (true);
 +                      MethodInfo set_accessor = base_property.GetSetMethod (true);
 +                      MethodAttributes get_accessor_access = 0, set_accessor_access = 0;
 +
 +                      //
 +                      // Check base property accessors conflict
 +                      //
 +                      if ((ModFlags & (Modifiers.OVERRIDE | Modifiers.NEW)) == Modifiers.OVERRIDE) {
 +                              if (get_accessor == null) {
 +                                      if (Get != null && !Get.IsDummy) {
 +                                              Report.SymbolRelatedToPreviousError (base_property);
 +                                              Report.Error (545, Location,
 +                                                      "`{0}.get': cannot override because `{1}' does not have an overridable get accessor",
 +                                                      GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
 +                                      }
 +                              } else {
 +                                      get_accessor_access = get_accessor.Attributes & MethodAttributes.MemberAccessMask;
 +
 +                                      if (!Get.IsDummy && !CheckAccessModifiers (
 +                                              ModifiersExtensions.MethodAttr (Get.ModFlags) & MethodAttributes.MemberAccessMask, get_accessor_access, get_accessor))
 +                                              Error_CannotChangeAccessModifiers (Get.Location, get_accessor, get_accessor_access, ".get");
 +                              }
 +
 +                              if (set_accessor == null) {
 +                                      if (Set != null && !Set.IsDummy) {
 +                                              Report.SymbolRelatedToPreviousError (base_property);
 +                                              Report.Error (546, Location,
 +                                                      "`{0}.set': cannot override because `{1}' does not have an overridable set accessor",
 +                                                      GetSignatureForError (), TypeManager.GetFullNameSignature (base_property));
 +                                      }
 +                              } else {
 +                                      set_accessor_access = set_accessor.Attributes & MethodAttributes.MemberAccessMask;
 +
 +                                      if (!Set.IsDummy && !CheckAccessModifiers (
 +                                              ModifiersExtensions.MethodAttr (Set.ModFlags) & MethodAttributes.MemberAccessMask, set_accessor_access, set_accessor))
 +                                              Error_CannotChangeAccessModifiers (Set.Location, set_accessor, set_accessor_access, ".set");
 +                              }
 +                      }
 +
 +                      // When one accessor does not exist and property hides base one
 +                      // we need to propagate this upwards
 +                      if (set_accessor == null)
 +                              set_accessor = get_accessor;
 +
 +                      //
 +                      // 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) {
 +                              if (OptAttributes != null)
 +                                      OptAttributes.Emit ();
 +
 +                              if (TypeManager.IsDynamicType (member_type)) {
 +                                      PredefinedAttributes.Get.Dynamic.EmitAttribute (PropertyBuilder);
 +                              } else {
 +                                      var trans_flags = TypeManager.HasDynamicTypeUsed (member_type);
 +                                      if (trans_flags != null) {
 +                                              var pa = PredefinedAttributes.Get.DynamicTransform;
 +                                              if (pa.Constructor != null || pa.ResolveConstructor (Location, TypeManager.bool_type.MakeArrayType ())) {
 +                                                      PropertyBuilder.SetCustomAttribute (
 +                                                              new CustomAttributeBuilder (pa.Constructor, new object [] { trans_flags }));
 +                                              }
 +                                      }
 +                              }
 +                      }
 +
 +                      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);
 +              }
 +
 +              public override bool IsUsed
 +              {
 +                      get {
 +                              if (IsExplicitImpl)
 +                                      return true;
 +
 +                              return Get.IsUsed | Set.IsUsed;
 +                      }
 +              }
 +
 +              protected override void SetMemberName (MemberName new_name)
 +              {
 +                      base.SetMemberName (new_name);
 +
 +                      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
 +      {
 +              public sealed class BackingField : Field
 +              {
 +                      readonly Property property;
 +
 +                      public BackingField (Property p)
 +                              : base (p.Parent, p.type_name,
 +                              Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (p.ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
 +                              new MemberName ("<" + p.GetFullName (p.MemberName) + ">k__BackingField", p.Location), null)
 +                      {
 +                              this.property = p;
 +                      }
 +
 +                      public override string GetSignatureForError ()
 +                      {
 +                              return property.GetSignatureForError ();
 +                      }
 +              }
 +
 +              const Modifiers AllowedModifiers =
 +                      Modifiers.NEW |
 +                      Modifiers.PUBLIC |
 +                      Modifiers.PROTECTED |
 +                      Modifiers.INTERNAL |
 +                      Modifiers.PRIVATE |
 +                      Modifiers.STATIC |
 +                      Modifiers.SEALED |
 +                      Modifiers.OVERRIDE |
 +                      Modifiers.ABSTRACT |
 +                      Modifiers.UNSAFE |
 +                      Modifiers.EXTERN |
 +                      Modifiers.VIRTUAL;
 +
 +              const Modifiers AllowedInterfaceModifiers =
 +                      Modifiers.NEW;
 +
 +              public Property (DeclSpace parent, FullNamedExpression type, Modifiers mod,
 +                               MemberName name, Attributes attrs, Accessor get_block,
 +                               Accessor set_block, bool define_set_first)
 +                      : this (parent, type, mod, name, attrs, get_block, set_block,
 +                              define_set_first, null)
 +              {
 +              }
 +              
 +              public Property (DeclSpace parent, FullNamedExpression type, Modifiers mod,
 +                               MemberName name, Attributes attrs, Accessor get_block,
 +                               Accessor set_block, bool define_set_first, Block current_block)
 +                      : base (parent, type, mod,
 +                              parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
 +                              name, attrs, define_set_first)
 +              {
 +                      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);
 +
 +                      if (!IsInterface && (mod & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0 &&
 +                              get_block != null && get_block.Block == null &&
 +                              set_block != null && set_block.Block == null) {
 +                              if (RootContext.Version <= LanguageVersion.ISO_2)
 +                                      Report.FeatureIsNotAvailable (Location, "automatically implemented properties");
 +
 +                              Get.ModFlags |= Modifiers.COMPILER_GENERATED;
 +                              Set.ModFlags |= Modifiers.COMPILER_GENERATED;
 +                      }
 +              }
 +
 +              void CreateAutomaticProperty ()
 +              {
 +                      // Create backing field
 +                      Field field = new BackingField (this);
 +                      if (!field.Define ())
 +                              return;
 +
 +                      Parent.PartialContainer.AddField (field);
 +
 +                      FieldExpr fe = new FieldExpr (field, Location);
 +                      if ((field.ModFlags & Modifiers.STATIC) == 0)
 +                              fe.InstanceExpression = new CompilerGeneratedThis (fe.Type, Location);
 +
 +                      // Create get block
 +                      Get.Block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location);
 +                      Return r = new Return (fe, Location);
 +                      Get.Block.AddStatement (r);
 +
 +                      // Create set block
 +                      Set.Block = new ToplevelBlock (Compiler, Set.ParameterInfo, Location);
 +                      Assign a = new SimpleAssign (fe, new SimpleName ("value", Location));
 +                      Set.Block.AddStatement (new StatementExpression (a));
 +              }
 +
 +              public override bool Define ()
 +              {
 +                      if (!base.Define ())
 +                              return false;
 +
 +                      flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
 +
 +                      if ((Get.ModFlags & Modifiers.COMPILER_GENERATED) != 0)
 +                              CreateAutomaticProperty ();
 +
 +                      if (!DefineAccessors ())
 +                              return false;
 +
 +                      if (!CheckBase ())
 +                              return false;
 +
 +                      // FIXME - PropertyAttributes.HasDefault ?
 +
 +                      PropertyBuilder = Parent.TypeBuilder.DefineProperty (
 +                              GetFullName (MemberName), PropertyAttributes.None, MemberType, null);
 +
 +                      if (!Get.IsDummy) {
 +                              PropertyBuilder.SetGetMethod (GetBuilder);
 +                              Parent.MemberCache.AddMember (GetBuilder, Get);
 +                      }
 +
 +                      if (!Set.IsDummy) {
 +                              PropertyBuilder.SetSetMethod (SetBuilder);
 +                              Parent.MemberCache.AddMember (SetBuilder, Set);
 +                      }
 +                      
 +                      TypeManager.RegisterProperty (PropertyBuilder, this);
 +                      Parent.MemberCache.AddMember (PropertyBuilder, this);
 +                      return true;
 +              }
 +
 +              public override void Emit ()
 +              {
 +                      if (((Set.ModFlags | Get.ModFlags) & (Modifiers.STATIC | Modifiers.COMPILER_GENERATED)) == Modifiers.COMPILER_GENERATED && Parent.PartialContainer.HasExplicitLayout) {
 +                              Report.Error (842, Location,
 +                                      "Automatically implemented property `{0}' cannot be used inside a type with an explicit StructLayout attribute",
 +                                      GetSignatureForError ());
 +                      }
 +
 +                      base.Emit ();
 +              }
 +
 +              protected override PropertyInfo ResolveBaseProperty ()
 +              {
 +                      return Parent.PartialContainer.BaseCache.FindMemberToOverride (
 +                              Parent.TypeBuilder, Name, ParametersCompiled.EmptyReadOnlyParameters, null, true) as PropertyInfo;
 +              }
 +      }
 +
 +      /// </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.SetAssigned ();
 +                              my_event.SetIsUsed ();
 +                      }
 +              }
 +      }
 +      
 +      /// <summary>
 +      /// For case when event is declared like property (with add and remove accessors).
 +      /// </summary>
 +      public class EventProperty: Event {
 +              abstract class AEventPropertyAccessor : AEventAccessor
 +              {
 +                      protected AEventPropertyAccessor (EventProperty method, Accessor accessor, string prefix)
 +                              : base (method, accessor, prefix)
 +                      {
 +                      }
 +
 +                      public override MethodBuilder Define (DeclSpace ds)
 +                      {
 +                              CheckAbstractAndExtern (block != null);
 +                              return base.Define (ds);
 +                      }
 +                      
 +                      public override string GetSignatureForError ()
 +                      {
 +                              return method.GetSignatureForError () + "." + prefix.Substring (0, prefix.Length - 1);
 +                      }
 +              }
 +
 +              sealed class AddDelegateMethod: AEventPropertyAccessor
 +              {
 +                      public AddDelegateMethod (EventProperty method, Accessor accessor):
 +                              base (method, accessor, AddPrefix)
 +                      {
 +                      }
 +              }
 +
 +              sealed class RemoveDelegateMethod: AEventPropertyAccessor
 +              {
 +                      public RemoveDelegateMethod (EventProperty method, Accessor accessor):
 +                              base (method, accessor, RemovePrefix)
 +                      {
 +                      }
 +              }
 +
 +
 +              static readonly string[] attribute_targets = new string [] { "event" }; // "property" target was disabled for 2.0 version
 +
 +              public EventProperty (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags,
 +                                    MemberName name,
 +                                    Attributes attrs, Accessor add, Accessor remove)
 +                      : base (parent, type, mod_flags, name, attrs)
 +              {
 +                      Add = new AddDelegateMethod (this, add);
 +                      Remove = new RemoveDelegateMethod (this, remove);
 +              }
 +
 +              public override bool Define()
 +              {
 +                      if (!base.Define ())
 +                              return false;
 +
 +                      SetIsUsed ();
 +                      return true;
 +              }
 +
 +              public override string[] ValidAttributeTargets {
 +                      get {
 +                              return attribute_targets;
 +                      }
 +              }
 +      }
 +
 +      /// <summary>
 +      /// Event is declared like field.
 +      /// </summary>
 +      public class EventField : Event {
 +              abstract class EventFieldAccessor : AEventAccessor
 +              {
 +                      protected EventFieldAccessor (EventField method, string prefix)
 +                              : base (method, prefix)
 +                      {
 +                      }
 +
 +                      public override void Emit (DeclSpace parent)
 +                      {
 +                              if ((method.ModFlags & (Modifiers.ABSTRACT | Modifiers.EXTERN)) == 0) {
 +                                      if (parent is Class) {
 +                                              MethodBuilder mb = method_data.MethodBuilder;
 +                                              mb.SetImplementationFlags (mb.GetMethodImplementationFlags () | MethodImplAttributes.Synchronized);
 +                                      }
 +
 +                                      var field_info = ((EventField) method).BackingField;
 +                                      FieldExpr f_expr = new FieldExpr (field_info, Location);
 +                                      if ((method.ModFlags & Modifiers.STATIC) == 0)
 +                                              f_expr.InstanceExpression = new CompilerGeneratedThis (field_info.Spec.FieldType, Location);
 +
 +                                      block = new ToplevelBlock (Compiler, ParameterInfo, Location);
 +                                      block.AddStatement (new StatementExpression (
 +                                              new CompoundAssign (Operation,
 +                                                      f_expr,
 +                                                      block.GetParameterReference (ParameterInfo[0].Name, Location))));
 +                              }
 +
 +                              base.Emit (parent);
 +                      }
 +
 +                      protected abstract Binary.Operator Operation { get; }
 +              }
 +
 +              sealed class AddDelegateMethod: EventFieldAccessor
 +              {
 +                      public AddDelegateMethod (EventField method):
 +                              base (method, AddPrefix)
 +                      {
 +                      }
 +
 +                      protected override Binary.Operator Operation {
 +                              get { return Binary.Operator.Addition; }
 +                      }
 +              }
 +
 +              sealed class RemoveDelegateMethod: EventFieldAccessor
 +              {
 +                      public RemoveDelegateMethod (EventField method):
 +                              base (method, RemovePrefix)
 +                      {
 +                      }
 +
 +                      protected override Binary.Operator Operation {
 +                              get { return Binary.Operator.Subtraction; }
 +                      }
 +              }
 +
 +
 +              static readonly string[] attribute_targets = new string [] { "event", "field", "method" };
 +              static readonly string[] attribute_targets_interface = new string[] { "event", "method" };
 +
 +              public Field BackingField;
 +              public Expression Initializer;
 +
 +              public EventField (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
 +                      : base (parent, type, mod_flags, name, attrs)
 +              {
 +                      Add = new AddDelegateMethod (this);
 +                      Remove = new RemoveDelegateMethod (this);
 +              }
 +
 +              public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
 +              {
 +                      if (a.Target == AttributeTargets.Field) {
 +                              BackingField.ApplyAttributeBuilder (a, cb, pa);
 +                              return;
 +                      }
 +
 +                      if (a.Target == AttributeTargets.Method) {
 +                              int errors = Report.Errors;
 +                              Add.ApplyAttributeBuilder (a, cb, pa);
 +                              if (errors == Report.Errors)
 +                                      Remove.ApplyAttributeBuilder (a, cb, pa);
 +                              return;
 +                      }
 +
 +                      base.ApplyAttributeBuilder (a, cb, pa);
 +              }
 +
 +              public override bool Define()
 +              {
 +                      if (!base.Define ())
 +                              return false;
 +
 +                      if (Initializer != null && (ModFlags & Modifiers.ABSTRACT) != 0) {
 +                              Report.Error (74, Location, "`{0}': abstract event cannot have an initializer",
 +                                      GetSignatureForError ());
 +                      }
 +
 +                      if (!HasBackingField) {
 +                              SetIsUsed ();
 +                              return true;
 +                      }
 +
 +                      // FIXME: We are unable to detect whether generic event is used because
 +                      // we are using FieldExpr instead of EventExpr for event access in that
 +                      // case.  When this issue will be fixed this hack can be removed.
 +                      if (TypeManager.IsGenericType (MemberType) || Parent.IsGeneric)
 +                              SetIsUsed ();
 +
 +                      if (Add.IsInterfaceImplementation)
 +                              SetIsUsed ();
 +
 +                      TypeManager.RegisterEventField (EventBuilder, this);
 +
 +                      BackingField = new Field (Parent,
 +                              new TypeExpression (MemberType, Location),
 +                              Modifiers.BACKING_FIELD | Modifiers.COMPILER_GENERATED | Modifiers.PRIVATE | (ModFlags & (Modifiers.STATIC | Modifiers.UNSAFE)),
 +                              MemberName, null);
 +
 +                      Parent.PartialContainer.AddField (BackingField);
 +                      BackingField.Initializer = Initializer;
 +                      BackingField.ModFlags &= ~Modifiers.COMPILER_GENERATED;
 +
 +                      // Call define because we passed fields definition
 +                      return BackingField.Define ();
 +              }
 +
 +              bool HasBackingField {
 +                      get {
 +                              return !IsInterface && (ModFlags & Modifiers.ABSTRACT) == 0;
 +                      }
 +              }
 +
 +              public override string[] ValidAttributeTargets 
 +              {
 +                      get {
 +                              return HasBackingField ? attribute_targets : attribute_targets_interface;
 +                      }
 +              }
 +      }
 +
 +      public abstract class Event : PropertyBasedMember {
 +              public abstract class AEventAccessor : AbstractPropertyEventMethod
 +              {
 +                      protected readonly Event method;
 +                      ImplicitParameter param_attr;
 +
 +                      static readonly string[] attribute_targets = new string [] { "method", "param", "return" };
 +
 +                      public const string AddPrefix = "add_";
 +                      public const string RemovePrefix = "remove_";
 +
 +                      protected AEventAccessor (Event method, string prefix)
 +                              : base (method, prefix)
 +                      {
 +                              this.method = method;
 +                              this.ModFlags = method.ModFlags;
 +                      }
 +
 +                      protected AEventAccessor (Event method, Accessor accessor, string prefix)
 +                              : base (method, accessor, prefix)
 +                      {
 +                              this.method = method;
 +                              this.ModFlags = method.ModFlags;
 +                      }
 +
 +                      public bool IsInterfaceImplementation {
 +                              get { return method_data.implementing != null; }
 +                      }
 +
 +                      public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
 +                      {
 +                              if (a.IsInternalMethodImplAttribute) {
 +                                      method.is_external_implementation = true;
 +                              }
 +
 +                              base.ApplyAttributeBuilder (a, cb, pa);
 +                      }
 +
 +                      protected override void ApplyToExtraTarget (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
 +                      {
 +                              if (a.Target == AttributeTargets.Parameter) {
 +                                      if (param_attr == null)
 +                                              param_attr = new ImplicitParameter (method_data.MethodBuilder);
 +
 +                                      param_attr.ApplyAttributeBuilder (a, cb, pa);
 +                                      return;
 +                              }
 +
 +                              base.ApplyAttributeBuilder (a, cb, pa);
 +                      }
 +
 +                      public override AttributeTargets AttributeTargets {
 +                              get {
 +                                      return AttributeTargets.Method;
 +                              }
 +                      }
 +
 +                      public override bool IsClsComplianceRequired ()
 +                      {
 +                              return method.IsClsComplianceRequired ();
 +                      }
 +
 +                      public virtual MethodBuilder Define (DeclSpace parent)
 +                      {
 +                              method_data = new MethodData (method, method.ModFlags,
 +                                      method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);
 +
 +                              if (!method_data.Define (parent, method.GetFullName (MemberName), Report))
 +                                      return null;
 +
 +                              MethodBuilder mb = method_data.MethodBuilder;
 +                              ParameterInfo.ApplyAttributes (mb);
 +                              return mb;
 +                      }
 +
 +                      public override Type ReturnType {
 +                              get {
 +                                      return TypeManager.void_type;
 +                              }
 +                      }
 +
 +                      public override ObsoleteAttribute GetObsoleteAttribute ()
 +                      {
 +                              return method.GetObsoleteAttribute ();
 +                      }
 +
 +                      public override string[] ValidAttributeTargets {
 +                              get {
 +                                      return attribute_targets;
 +                              }
 +                      }
 +
 +                      public override ParametersCompiled ParameterInfo {
 +                              get {
 +                                      return method.parameters;
 +                              }
 +                      }
 +              }
 +
 +
 +              const Modifiers AllowedModifiers =
 +                      Modifiers.NEW |
 +                      Modifiers.PUBLIC |
 +                      Modifiers.PROTECTED |
 +                      Modifiers.INTERNAL |
 +                      Modifiers.PRIVATE |
 +                      Modifiers.STATIC |
 +                      Modifiers.VIRTUAL |
 +                      Modifiers.SEALED |
 +                      Modifiers.OVERRIDE |
 +                      Modifiers.UNSAFE |
 +                      Modifiers.ABSTRACT |
 +                      Modifiers.EXTERN;
 +
 +              const Modifiers AllowedInterfaceModifiers =
 +                      Modifiers.NEW;
 +
 +              public AEventAccessor Add, Remove;
 +              public MyEventBuilder     EventBuilder;
 +              public MethodBuilder AddBuilder, RemoveBuilder;
 +
 +              ParametersCompiled parameters;
 +
 +              protected Event (DeclSpace parent, FullNamedExpression type, Modifiers mod_flags, MemberName name, Attributes attrs)
 +                      : base (parent, null, type, mod_flags,
 +                              parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
 +                              name, attrs)
 +              {
 +              }
 +
 +              public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder cb, PredefinedAttributes pa)
 +              {
 +                      if ((a.HasSecurityAttribute)) {
 +                              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 ()
 +              {
 +                      if (!base.Define ())
 +                              return false;
 +
 +                      if (!TypeManager.IsDelegateType (MemberType)) {
 +                              Report.Error (66, Location, "`{0}': event must be of a delegate type", GetSignatureForError ());
 +                      }
 +
 +                      parameters = ParametersCompiled.CreateFullyResolved (
 +                              new Parameter (null, "value", Parameter.Modifier.NONE, null, Location), MemberType);
 +
 +                      if (!CheckBase ())
 +                              return false;
 +
 +                      if (TypeManager.delegate_combine_delegate_delegate == null) {
 +                              TypeManager.delegate_combine_delegate_delegate = TypeManager.GetPredefinedMethod (
 +                                      TypeManager.delegate_type, "Combine", Location,
 +                                      TypeManager.delegate_type, TypeManager.delegate_type);
 +                      }
 +                      if (TypeManager.delegate_remove_delegate_delegate == null) {
 +                              TypeManager.delegate_remove_delegate_delegate = TypeManager.GetPredefinedMethod (
 +                                      TypeManager.delegate_type, "Remove", Location,
 +                                      TypeManager.delegate_type, TypeManager.delegate_type);
 +                      }
 +
 +                      //
 +                      // Now define the accessors
 +                      //
 +
 +                      AddBuilder = Add.Define (Parent);
 +                      if (AddBuilder == null)
 +                              return false;
 +
 +                      RemoveBuilder = Remove.Define (Parent);
 +                      if (RemoveBuilder == null)
 +                              return false;
 +
 +                      EventBuilder = new MyEventBuilder (this, Parent.TypeBuilder, Name, EventAttributes.None, MemberType);                                           
 +                      EventBuilder.SetAddOnMethod (AddBuilder);
 +                      EventBuilder.SetRemoveOnMethod (RemoveBuilder);
 +
 +                      Parent.MemberCache.AddMember (EventBuilder, this);
 +                      Parent.MemberCache.AddMember (AddBuilder, Add);
 +                      Parent.MemberCache.AddMember (RemoveBuilder, Remove);
 +                      
 +                      return true;
 +              }
 +
 +              public override void Emit ()
 +              {
 +                      if (OptAttributes != null) {
 +                              OptAttributes.Emit ();
 +                      }
 +
 +                      Add.Emit (Parent);
 +                      Remove.Emit (Parent);
 +
 +                      base.Emit ();
 +              }
 +
 +              protected override MethodInfo FindOutBaseMethod (ref Type base_ret_type)
 +              {
 +                      MethodInfo mi = (MethodInfo) Parent.PartialContainer.BaseCache.FindBaseEvent (
 +                              Parent.TypeBuilder, Name);
 +
 +                      if (mi == null)
 +                              return null;
 +
 +                      AParametersCollection pd = TypeManager.GetParameterData (mi);
 +                      base_ret_type = pd.Types [0];
 +                      return mi;
 +              }
 +
 +              //
 +              //   Represents header string for documentation comment.
 +              //
 +              public override string DocCommentHeader {
 +                      get { return "E:"; }
 +              }
 +      }
 + 
 +      public class Indexer : PropertyBase
 +      {
 +              public class GetIndexerMethod : GetMethod
 +              {
 +                      ParametersCompiled parameters;
 +
 +                      public GetIndexerMethod (Indexer method):
 +                              base (method)
 +                      {
 +                              this.parameters = method.parameters;
 +                      }
 +
 +                      public GetIndexerMethod (PropertyBase method, Accessor accessor):
 +                              base (method, accessor)
 +                      {
 +                              parameters = accessor.Parameters;
 +                      }
 +
 +                      public override MethodBuilder Define (DeclSpace parent)
 +                      {
 +                              parameters.Resolve (this);
 +                              return base.Define (parent);
 +                      }
 +                      
 +                      public override bool EnableOverloadChecks (MemberCore overload)
 +                      {
 +                              if (base.EnableOverloadChecks (overload)) {
 +                                      overload.caching_flags |= Flags.MethodOverloadsExist;
 +                                      return true;
 +                              }
 +
 +                              return false;
 +                      }                       
 +
 +                      public override ParametersCompiled ParameterInfo {
 +                              get {
 +                                      return parameters;
 +                              }
 +                      }
 +              }
 +
 +              public class SetIndexerMethod: SetMethod
 +              {
 +                      public SetIndexerMethod (Indexer method):
 +                              base (method)
 +                      {
 +                              parameters = ParametersCompiled.MergeGenerated (Compiler, method.parameters, false, parameters [0], null);
 +                      }
 +
 +                      public SetIndexerMethod (PropertyBase method, Accessor accessor):
 +                              base (method, accessor)
 +                      {
 +                              parameters = method.Get.IsDummy ? accessor.Parameters : accessor.Parameters.Clone ();                   
 +                      }
 +
 +                      public override bool EnableOverloadChecks (MemberCore overload)
 +                      {
 +                              if (base.EnableOverloadChecks (overload)) {
 +                                      overload.caching_flags |= Flags.MethodOverloadsExist;
 +                                      return true;
 +                              }
 +
 +                              return false;
 +                      }
 +              }
 +
 +              const Modifiers AllowedModifiers =
 +                      Modifiers.NEW |
 +                      Modifiers.PUBLIC |
 +                      Modifiers.PROTECTED |
 +                      Modifiers.INTERNAL |
 +                      Modifiers.PRIVATE |
 +                      Modifiers.VIRTUAL |
 +                      Modifiers.SEALED |
 +                      Modifiers.OVERRIDE |
 +                      Modifiers.UNSAFE |
 +                      Modifiers.EXTERN |
 +                      Modifiers.ABSTRACT;
 +
 +              const Modifiers AllowedInterfaceModifiers =
 +                      Modifiers.NEW;
 +
 +              public readonly ParametersCompiled parameters;
 +
 +              public Indexer (DeclSpace parent, FullNamedExpression type, MemberName name, Modifiers mod,
 +                              ParametersCompiled parameters, Attributes attrs,
 +                              Accessor get_block, Accessor set_block, bool define_set_first)
 +                      : base (parent, type, mod,
 +                              parent.PartialContainer.Kind == Kind.Interface ? AllowedInterfaceModifiers : AllowedModifiers,
 +                              name, attrs, define_set_first)
 +              {
 +                      this.parameters = parameters;
 +
 +                      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, set_block);
 +              }
 +
 +              protected override bool CheckForDuplications ()
 +              {
 +                      return Parent.MemberCache.CheckExistingMembersOverloads (this, GetFullName (MemberName), parameters, Report);
 +              }
 +              
 +              public override bool Define ()
 +              {
 +                      if (!base.Define ())
 +                              return false;
 +
 +                      if (!DefineParameters (parameters))
 +                              return false;
 +
 +                      if (OptAttributes != null) {
 +                              Attribute indexer_attr = OptAttributes.Search (PredefinedAttributes.Get.IndexerName);
 +                              if (indexer_attr != null) {
 +                                      // Remove the attribute from the list because it is not emitted
 +                                      OptAttributes.Attrs.Remove (indexer_attr);
 +
 +                                      string name = indexer_attr.GetIndexerAttributeValue ();
 +                                      if (name == null)
 +                                              return false;
 +
 +                                      ShortName = name;
 +
 +                                      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 (InterfaceType != null) {
 +                              string base_IndexerName = TypeManager.IndexerPropertyName (InterfaceType);
 +                              if (base_IndexerName != Name)
 +                                      ShortName = base_IndexerName;
 +                      }
 +
 +                      if (!Parent.PartialContainer.AddMember (this) ||
 +                              !Parent.PartialContainer.AddMember (Get) || !Parent.PartialContainer.AddMember (Set))
 +                              return false;
 +
 +                      flags |= MethodAttributes.HideBySig | MethodAttributes.SpecialName;
 +                      
 +                      if (!DefineAccessors ())
 +                              return false;
 +
 +                      if (!CheckBase ())
 +                              return false;
 +
 +                      //
 +                      // Now name the parameters
 +                      //
 +                      PropertyBuilder = Parent.TypeBuilder.DefineProperty (
 +                              GetFullName (MemberName), PropertyAttributes.None, MemberType, parameters.GetEmitTypes ());
 +
 +                      if (!Get.IsDummy) {
 +                              PropertyBuilder.SetGetMethod (GetBuilder);
 +                              Parent.MemberCache.AddMember (GetBuilder, Get);
 +                      }
 +
 +                      if (!Set.IsDummy) {
 +                              PropertyBuilder.SetSetMethod (SetBuilder);
 +                              Parent.MemberCache.AddMember (SetBuilder, Set);
 +                      }
 +                              
 +                      TypeManager.RegisterIndexer (PropertyBuilder, parameters);
 +                      Parent.MemberCache.AddMember (PropertyBuilder, this);
 +                      return true;
 +              }
 +
 +              public override bool EnableOverloadChecks (MemberCore overload)
 +              {
 +                      if (overload is Indexer) {
 +                              caching_flags |= Flags.MethodOverloadsExist;
 +                              return true;
 +                      }
 +
 +                      return base.EnableOverloadChecks (overload);
 +              }
 +
 +              public override string GetDocCommentName (DeclSpace ds)
 +              {
 +                      return DocUtil.GetMethodDocCommentName (this, parameters, ds);
 +              }
 +
 +              public override string GetSignatureForError ()
 +              {
 +                      StringBuilder sb = new StringBuilder (Parent.GetSignatureForError ());
 +                      if (MemberName.Left != null) {
 +                              sb.Append ('.');
 +                              sb.Append (MemberName.Left.GetSignatureForError ());
 +                      }
 +
 +                      sb.Append (".this");
 +                      sb.Append (parameters.GetSignatureForError ().Replace ('(', '[').Replace (')', ']'));
 +                      return sb.ToString ();
 +              }
 +
 +              protected override PropertyInfo ResolveBaseProperty ()
 +              {
 +                      return Parent.PartialContainer.BaseCache.FindMemberToOverride (
 +                              Parent.TypeBuilder, Name, parameters, null, true) as PropertyInfo;
 +              }
 +
 +              protected override bool VerifyClsCompliance ()
 +              {
 +                      if (!base.VerifyClsCompliance ())
 +                              return false;
 +
 +                      parameters.VerifyClsCompliance (this);
 +                      return true;
 +              }
 +      }
 +}
index 891cd8490e25f41ede6933f49ccf23ad8b879105,96bc5d3d73304ec6bf211186eb7a947286ee347f..208d2eee290e24e7cef5ea9e5990b66127ccff3f
@@@ -30,6 -30,6 +30,7 @@@ lambda.c
  linq.cs
  literal.cs
  location.cs
++membercache.cs
  method.cs
  modifiers.cs
  namespace.cs
@@@ -43,6 -42,6 +44,7 @@@ roottypes.c
  statement.cs
  support.cs
  typemanager.cs
++typespec.cs
  symbolwriter.cs
  ../class/Mono.CompilerServices.SymbolWriter/MonoSymbolFile.cs
  ../class/Mono.CompilerServices.SymbolWriter/MonoSymbolTable.cs
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..641e37707edcfd092597ffc06913e1c588590e55
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,69 @@@
++//
++// typespec.cs: Type specification
++//
++// Authors: Marek Safar (marek.safar@gmail.com)
++//
++// Dual licensed under the terms of the MIT X11 or GNU GPL
++//
++// Copyright 2010 Novell, Inc
++//
++
++using System;
++using System.Collections.Generic;
++
++namespace Mono.CSharp
++{
++      public class TypeSpec : MemberSpec
++      {
++              Type info;
++              protected MemberCache cache;
++
++              public TypeSpec (MemberKind kind, ITypeDefinition definition, Type info, string name, Modifiers modifiers)
++                      : base (kind, definition, name, modifiers)
++              {
++                      this.info = info;
++              }
++
++              public TypeSpec BaseType { get; set; }
++
++              public override Type DeclaringType {
++                      get { return info.DeclaringType; }
++              }
++
++              public Type MetaInfo {
++                      get { return info; }
++              }
++
++              public MemberCache MemberCache {
++                      get {
++                              if (cache == null) {
++//                                    cache = new MemberCache (BaseType);
++
++//                                    ((ITypeDefinition) definition).LoadMembers (cache);
++                              }
++
++                              return cache;
++                      }
++              }
++      }
++
++      public interface ITypeDefinition : IMemberDefinition
++      {
++              void LoadMembers (MemberCache cache);
++      }
++/*
++      class InternalType : TypeSpec
++      {
++              public static readonly TypeSpec AnonymousMethod = new InternalType ("anonymous method");
++              public static readonly TypeSpec Arglist = new InternalType ("__arglist");
++//            public static readonly TypeSpec Dynamic = new DynamicType ();
++              public static readonly TypeSpec MethodGroup = new InternalType ("method group");
++
++              protected InternalType (string name)
++                      : base (null, null, name, Modifiers.PUBLIC)
++              {
++//                    cache = MemberCache.Empty;
++              }
++      }
++*/ 
++}