protected void CheckReservedNameConflict (string prefix, MethodSpec accessor)
		{
			string name;
			AParametersCollection parameters;
			if (accessor != null) {
				name = accessor.Name;
				parameters = accessor.Parameters;
			} else {
				name = prefix + ShortName;
				if (IsExplicitImpl)
					name = MemberName.Left + "." + name;

				if (this is Indexer) {
					parameters = ((Indexer) this).ParameterInfo;
					if (prefix[0] == 's') {
						var data = new IParameterData[parameters.Count + 1];
						Array.Copy (parameters.FixedParameters, data, data.Length - 1);
						data[data.Length - 1] = new ParameterData ("value", Parameter.Modifier.NONE);
						var types = new TypeSpec[data.Length];
						Array.Copy (parameters.Types, types, data.Length - 1);
						types[data.Length - 1] = member_type;

						parameters = new ParametersImported (data, types, false);
					}
				} else {
					if (prefix[0] == 's')
						parameters = ParametersCompiled.CreateFullyResolved (new[] { member_type });
					else
						parameters = ParametersCompiled.EmptyReadOnlyParameters;
				}
			}

			var conflict = MemberCache.FindMember (Parent.Definition,
				new MemberFilter (name, 0, MemberKind.Method, parameters, null),
				BindingRestriction.DeclaredOnly | BindingRestriction.NoAccessors);

			if (conflict != null) {
				Report.SymbolRelatedToPreviousError (conflict);
				Report.Error (82, Location, "A member `{0}' is already reserved", conflict.GetSignatureForError ());
			}
		}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
#if false
			if (a.Type == pa.MarshalAs) {
				UnmanagedMarshal marshal = a.GetMarshal (this);
				if (marshal != null) {
					builder.SetMarshal (marshal);
				}
				return;
			}
#endif
			if (a.HasSecurityAttribute) {
				a.Error_InvalidSecurityParent ();
				return;
			}

			if (a.Type == pa.Dynamic) {
				a.Error_MisusedDynamicAttribute ();
				return;
			}

			builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
		}
		public MethodData (InterfaceMemberBase member,
				   Modifiers modifiers, MethodAttributes flags, 
				   IMethodData method, MethodBuilder builder,
				   MethodSpec parent_method)
			: this (member, modifiers, flags, method)
		{
			this.builder = builder;
			this.parent_method = parent_method;
		}
		/// <summary>
		///   This function tells whether one of our base classes implements
		///   the given method (which turns out, it is valid to have an interface
		///   implementation in a base
		/// </summary>
		bool BaseImplements (TypeSpec iface_type, MethodSpec mi, out MethodSpec base_method)
		{
			base_method = null;
			var base_type = container.BaseType;

			//
			// Setup filter with no return type to give better error message
			// about mismatch at return type when the check bellow rejects them
			//
			var parameters = mi.Parameters;
			while (true) {
				var candidates = MemberCache.FindMembers (base_type, mi.Name, false);
				if (candidates == null)
					return false;

				MethodSpec similar_candidate = null;
				foreach (var candidate in candidates) {
					if (candidate.Kind != MemberKind.Method)
						continue;

					if (candidate.Arity != mi.Arity)
						continue;

					var candidate_param = ((MethodSpec) candidate).Parameters;
					if (!TypeSpecComparer.Override.IsEqual (parameters.Types, candidate_param.Types))
						continue;

					bool modifiers_match = true;
					for (int i = 0; i < parameters.Count; ++i) {
						//
						// First check exact ref/out match
						//
						if ((parameters.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) == (candidate_param.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask))
							continue;

						modifiers_match = false;

						//
						// Different in ref/out only
						//
						if ((parameters.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (candidate_param.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask)) {
							if (similar_candidate == null) {
								if (!candidate.IsPublic)
									break;

								if (!TypeSpecComparer.Override.IsEqual (mi.ReturnType, ((MethodSpec) candidate).ReturnType))
									break;

								// It's used for ref/out ambiguity overload check
								similar_candidate = (MethodSpec) candidate;
							}

							continue;
						}

						similar_candidate = null;
						break;
					}

					if (!modifiers_match)
						continue;

					//
					// From this point the candidate is used for detailed error reporting
					// because it's very close match to what we are looking for
					//
					base_method = (MethodSpec) candidate;

					if (!candidate.IsPublic)
						return false;

					if (!TypeSpecComparer.Override.IsEqual (mi.ReturnType, base_method.ReturnType))
						return false;

					if (mi.IsGeneric && !Method.CheckImplementingMethodConstraints (container, base_method, mi)) {
						return true;
					}
				}

				if (base_method != null) {
					if (similar_candidate != null) {
						Report.SymbolRelatedToPreviousError (similar_candidate);
						Report.SymbolRelatedToPreviousError (mi);
						Report.SymbolRelatedToPreviousError (container);
						Report.Warning (1956, 1, ((MemberCore) base_method.MemberDefinition).Location,
							"The interface method `{0}' implementation is ambiguous between following methods: `{1}' and `{2}' in type `{3}'",
							mi.GetSignatureForError (), base_method.GetSignatureForError (), similar_candidate.GetSignatureForError (), container.GetSignatureForError ());
					}

					break;
				}

				base_type = candidates[0].DeclaringType.BaseType;
				if (base_type == null)
					return false;
			}

			if (!base_method.IsVirtual) {
#if STATIC
				var base_builder = base_method.GetMetaInfo () as MethodBuilder;
				if (base_builder != null) {
					//
					// We can avoid creating a proxy if base_method can be marked 'final virtual'. This can
					// be done for all methods from compiled assembly
					//
					base_builder.__SetAttributes (base_builder.Attributes | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot);
					return true;
				}
#endif
				DefineProxy (iface_type, base_method, mi);
			}

			return true;
		}
		/// <remarks>
		///   If a method in Type `t' (or null to look in all interfaces
		///   and the base abstract class) with name `Name', return type `ret_type' and
		///   arguments `args' implements an interface, this method will
		///   return the MethodInfo that this method implements.
		///
		///   If `name' is null, we operate solely on the method's signature.  This is for
		///   instance used when implementing indexers.
		///
		///   The `Operation op' controls whether to lookup, clear the pending bit, or clear
		///   all the methods with the given signature.
		///
		///   The `MethodInfo need_proxy' is used when we're implementing an interface's
		///   indexer in a class.  If the new indexer's IndexerName does not match the one
		///   that was used in the interface, then we always need to create a proxy for it.
		///
		/// </remarks>
		public MethodSpec InterfaceMethod (MemberName name, TypeSpec iType, MethodData method, Operation op, out MethodSpec ambiguousCandidate, ref bool optional)
		{
			ambiguousCandidate = null;

			if (pending_implementations == null)
				return null;

			TypeSpec ret_type = method.method.ReturnType;
			ParametersCompiled args = method.method.ParameterInfo;
			bool is_indexer = method.method is Indexer.SetIndexerMethod || method.method is Indexer.GetIndexerMethod;
			MethodSpec m;

			foreach (TypeAndMethods tm in pending_implementations){
				if (!(iType == null || tm.type == iType))
					continue;

				int method_count = tm.methods.Count;
				for (int i = 0; i < method_count; i++){
					m = tm.methods [i];

					if (m == null)
						continue;

					if (is_indexer) {
						if (!m.IsAccessor || m.Parameters.IsEmpty)
							continue;
					} else {
						if (name.Name != m.Name)
							continue;

						if (m.Arity != name.Arity)
							continue;
					}

					if (!TypeSpecComparer.Override.IsEqual (m.Parameters, args))
						continue;

					if (!TypeSpecComparer.Override.IsEqual (m.ReturnType, ret_type)) {
						tm.found[i] = method;
						continue;
					}

					//
					// `need_proxy' is not null when we're implementing an
					// interface indexer and this is Clear(One/All) operation.
					//
					// If `name' is null, then we do a match solely based on the
					// signature and not on the name (this is done in the Lookup
					// for an interface indexer).
					//
					if (op != Operation.Lookup) {
						if (m.IsAccessor != method.method.IsAccessor)
							continue;

						// If `t != null', then this is an explicitly interface
						// implementation and we can always clear the method.
						// `need_proxy' is not null if we're implementing an
						// interface indexer.  In this case, we need to create
						// a proxy if the implementation's IndexerName doesn't
						// match the IndexerName in the interface.
						if (m.DeclaringType.IsInterface && iType == null && name.Name != m.Name) {	// TODO: This is very expensive comparison
							tm.need_proxy[i] = method.method.Spec;
						} else {
							tm.methods[i] = null;
						}
					} else {
						tm.found [i] = method;
						optional = tm.optional;
					}

					if (op == Operation.Lookup && name.ExplicitInterface != null && ambiguousCandidate == null) {
						ambiguousCandidate = m;
						continue;
					}

					//
					// Lookups and ClearOne return
					//
					if (op != Operation.ClearAll)
						return m;
				}

				// If a specific type was requested, we can stop now.
				if (tm.type == iType)
					break;
			}

			m = ambiguousCandidate;
			ambiguousCandidate = null;
			return m;
		}
		/// <summary>
		///   Whether the specified method is an interface method implementation
		/// </summary>
		public MethodSpec IsInterfaceMethod (MemberName name, TypeSpec ifaceType, MethodData method, out MethodSpec ambiguousCandidate, ref bool optional)
		{
			return InterfaceMethod (name, ifaceType, method, Operation.Lookup, out ambiguousCandidate, ref optional);
		}
		PendingImplementation (TypeDefinition container, MissingInterfacesInfo[] missing_ifaces, MethodSpec[] abstract_methods, int total)
		{
			var type_builder = container.Definition;
			
			this.container = container;
			pending_implementations = new TypeAndMethods [total];

			int i = 0;
			if (abstract_methods != null) {
				int count = abstract_methods.Length;
				pending_implementations [i].methods = new MethodSpec [count];
				pending_implementations [i].need_proxy = new MethodSpec [count];

				pending_implementations [i].methods = abstract_methods;
				pending_implementations [i].found = new MethodData [count];
				pending_implementations [i].type = type_builder;
				++i;
			}

			foreach (MissingInterfacesInfo missing in missing_ifaces) {
				var iface = missing.Type;
				var mi = MemberCache.GetInterfaceMethods (iface);

				int count = mi.Count;
				pending_implementations [i].type = iface;
				pending_implementations [i].optional = missing.Optional;
				pending_implementations [i].methods = mi;
				pending_implementations [i].found = new MethodData [count];
				pending_implementations [i].need_proxy = new MethodSpec [count];
				i++;
			}
		}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if (a.HasSecurityAttribute) {
				a.Error_InvalidSecurityParent ();
				return;
			}

			if (a.Type == pa.Dynamic) {
				a.Error_MisusedDynamicAttribute ();
				return;
			}

			PropertyBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
		}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if (a.Type == pa.Conditional) {
				if (IsExplicitImpl) {
					Error_ConditionalAttributeIsNotValid ();
					return;
				}

				if ((ModFlags & Modifiers.OVERRIDE) != 0) {
					Report.Error (243, Location, "Conditional not valid on `{0}' because it is an override method", GetSignatureForError ());
					return;
				}

				if (ReturnType.Kind != MemberKind.Void) {
					Report.Error (578, Location, "Conditional not valid on `{0}' because its return type is not void", GetSignatureForError ());
					return;
				}

				if (IsInterface) {
					Report.Error (582, Location, "Conditional not valid on interface members");
					return;
				}

				if (MethodData.implementing != null) {
					Report.SymbolRelatedToPreviousError (MethodData.implementing.DeclaringType);
					Report.Error (629, Location, "Conditional member `{0}' cannot implement interface member `{1}'",
						GetSignatureForError (), TypeManager.CSharpSignature (MethodData.implementing));
					return;
				}

				for (int i = 0; i < parameters.Count; ++i) {
					if ((parameters.FixedParameters [i].ModFlags & Parameter.Modifier.OUT) != 0) {
						Report.Error (685, Location, "Conditional method `{0}' cannot have an out parameter", GetSignatureForError ());
						return;
					}
				}
			}

			if (a.Type == pa.Extension) {
				a.Error_MisusedExtensionAttribute ();
				return;
			}

			base.ApplyAttributeBuilder (a, ctor, cdata, pa);
		}
		public override bool Define ()
		{
			if (!base.Define ())
				return false;

			if (!CheckBase ())
				return false;

			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;

				// Add to member cache only when a partial method implementation has not been found yet
				if ((caching_flags & Flags.PartialDefinitionExists) == 0) {
//					MethodBase mb = new PartialMethodDefinitionInfo (this);

					spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, null, parameters, ModFlags);
					if (MemberName.Arity > 0) {
						spec.IsGeneric = true;

						// TODO: Have to move DefineMethod after Define (ideally to Emit)
						throw new NotImplementedException ("Generic partial methods");
					}

					Parent.MemberCache.AddMember (spec);
				}

				return true;
			}

			MethodData = new MethodData (
				this, ModFlags, flags, this, MethodBuilder, base_method);

			if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName)))
				return false;
					
			MethodBuilder = MethodData.MethodBuilder;

			spec = new MethodSpec (kind, Parent.Definition, this, ReturnType, MethodBuilder, parameters, ModFlags);
			if (MemberName.Arity > 0)
				spec.IsGeneric = true;
			
			Parent.MemberCache.AddMember (this, MethodBuilder.Name, spec);

			return true;
		}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if (a.Target == AttributeTargets.ReturnValue) {
				if (return_attributes == null)
					return_attributes = new ReturnParameter (this, MethodBuilder, Location);

				return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
				return;
			}

			if (a.Type == pa.MethodImpl) {
				if ((ModFlags & Modifiers.ASYNC) != 0 && (a.GetMethodImplOptions () & MethodImplOptions.Synchronized) != 0) {
					Report.Error (4015, a.Location, "`{0}': Async methods cannot use `MethodImplOptions.Synchronized'",
						GetSignatureForError ());
				}

				is_external_implementation = a.IsInternalCall ();
			} else if (a.Type == pa.DllImport) {
				const Modifiers extern_static = Modifiers.EXTERN | Modifiers.STATIC;
				if ((ModFlags & extern_static) != extern_static) {
					Report.Error (601, a.Location, "The DllImport attribute must be specified on a method marked `static' and `extern'");
				}
				is_external_implementation = true;
			}

			if (a.IsValidSecurityAttribute ()) {
				a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
				return;
			}

			if (MethodBuilder != null)
				MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
		}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if (a.Type == pa.Conditional) {
				Error_ConditionalAttributeIsNotValid ();
				return;
			}

			base.ApplyAttributeBuilder (a, ctor, cdata, pa);
		}
		protected virtual void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			throw new NotSupportedException ("You forgot to define special attribute target handling");
		}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if (a.Type == pa.CLSCompliant || a.Type == pa.Obsolete || a.Type == pa.Conditional) {
				Report.Error (1667, a.Location,
					"Attribute `{0}' is not valid on property or event accessors. It is valid on `{1}' declarations only",
					TypeManager.CSharpName (a.Type), a.GetValidTargets ());
				return;
			}

			if (a.IsValidSecurityAttribute ()) {
				a.ExtractSecurityPermissionSet (ctor, ref declarative_security);
				return;
			}

			if (a.Target == AttributeTargets.Method) {
				method_data.MethodBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
				return;
			}

			if (a.Target == AttributeTargets.ReturnValue) {
				if (return_attributes == null)
					return_attributes = new ReturnParameter (this, method_data.MethodBuilder, Location);

				return_attributes.ApplyAttributeBuilder (a, ctor, cdata, pa);
				return;
			}

			ApplyToExtraTarget (a, ctor, cdata, pa);
		}
		public bool Define (TypeDefinition container, string method_full_name)
		{
			PendingImplementation pending = container.PendingImplementations;
			MethodSpec ambig_iface_method;
			bool optional = false;

			if (pending != null) {
				implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method, ref optional);

				if (member.InterfaceType != null) {
					if (implementing == null) {
						if (member is PropertyBase) {
							container.Compiler.Report.Error (550, method.Location,
								"`{0}' is an accessor not found in interface member `{1}{2}'",
									  method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType),
									  member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.')));

						} else {
							container.Compiler.Report.Error (539, method.Location,
									  "`{0}.{1}' in explicit interface declaration is not a member of interface",
									  TypeManager.CSharpName (member.InterfaceType), member.ShortName);
						}
						return false;
					}
					if (implementing.IsAccessor && !method.IsAccessor) {
						container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
						container.Compiler.Report.Error (683, method.Location,
							"`{0}' explicit method implementation cannot implement `{1}' because it is an accessor",
							member.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
						return false;
					}
				} else {
					if (implementing != null) {
						if (!method.IsAccessor) {
							if (implementing.IsAccessor) {
								container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
								container.Compiler.Report.Error (470, method.Location,
									"Method `{0}' cannot implement interface accessor `{1}'",
									method.GetSignatureForError (), TypeManager.CSharpSignature (implementing));
							}
						} else if (implementing.DeclaringType.IsInterface) {
							if (!implementing.IsAccessor) {
								container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
								container.Compiler.Report.Error (686, method.Location,
									"Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation",
									method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ());
							} else {
								PropertyBase.PropertyMethod pm = method as PropertyBase.PropertyMethod;
								if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) {
									container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
									container.Compiler.Report.Error (277, method.Location,
										"Accessor `{0}' must be declared public to implement interface member `{1}'",
										method.GetSignatureForError (), implementing.GetSignatureForError ());
								}
							}
						}
					}
				}
			} else {
				ambig_iface_method = null;
			}

			//
			// For implicit implementations, make sure we are public, for
			// explicit implementations, make sure we are private.
			//
			if (implementing != null){
				if (member.IsExplicitImpl) {
					if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) {
						container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
						container.Compiler.Report.Error (466, method.Location,
							"`{0}': the explicit interface implementation cannot introduce the params modifier",
							method.GetSignatureForError ());
					}

					if (ambig_iface_method != null) {
						container.Compiler.Report.SymbolRelatedToPreviousError (ambig_iface_method);
						container.Compiler.Report.SymbolRelatedToPreviousError (implementing);
						container.Compiler.Report.Warning (473, 2, method.Location,
							"Explicit interface implementation `{0}' matches more than one interface member. Consider using a non-explicit implementation instead",
							method.GetSignatureForError ());
					}
				} else {
					//
					// Setting implementin to null inside this block will trigger a more
					// verbose error reporting for missing interface implementations
					//
					if (implementing.DeclaringType.IsInterface) {
						//
						// If this is an interface method implementation,
						// check for public accessibility
						//
						if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) {
							implementing = null;
						} else if (optional && (container.Interfaces == null || !container.Definition.Interfaces.Contains (implementing.DeclaringType))) {
							//
							// We are not implementing interface when base class already implemented it
							//
							implementing = null;
						}
					} else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private) {
						// We may never be private.
						implementing = null;

					} else if ((modifiers & Modifiers.OVERRIDE) == 0) {
						//
						// We may be protected if we're overriding something.
						//
						implementing = null;
					}
				}
					
				//
				// Static is not allowed
				//
				if ((modifiers & Modifiers.STATIC) != 0){
					implementing = null;
				}
			}
			
			//
			// If implementing is still valid, set flags
			//
			if (implementing != null){
				//
				// When implementing interface methods, set NewSlot
				// unless, we are overwriting a method.
				//
				if ((modifiers & Modifiers.OVERRIDE) == 0 && implementing.DeclaringType.IsInterface) {
					flags |= MethodAttributes.NewSlot;
				}

				flags |= MethodAttributes.Virtual | MethodAttributes.HideBySig;

				// Set Final unless we're virtual, abstract or already overriding a method.
				if ((modifiers & (Modifiers.VIRTUAL | Modifiers.ABSTRACT | Modifiers.OVERRIDE)) == 0)
					flags |= MethodAttributes.Final;

				//
				// clear the pending implementation flag (requires explicit methods to be defined first)
				//
				pending.ImplementMethod (method.MethodName,
					member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method, ref optional);

				//
				// Update indexer accessor name to match implementing abstract accessor
				//
				if (!implementing.DeclaringType.IsInterface && !member.IsExplicitImpl && implementing.IsAccessor)
					method_full_name = implementing.MemberDefinition.Name;
			}

			DefineMethodBuilder (container, method_full_name, method.ParameterInfo);

			if (builder == null)
				return false;

//			if (container.CurrentType != null)
//				declaring_type = container.CurrentType;
//			else
				declaring_type = container.Definition;

			if (implementing != null && member.IsExplicitImpl) {
				container.TypeBuilder.DefineMethodOverride (builder, (MethodInfo) implementing.GetMetaInfo ());
			}

			return true;
		}
			public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
			{
				if (a.Type == pa.MethodImpl) {
					method.is_external_implementation = a.IsInternalCall ();
				}

				base.ApplyAttributeBuilder (a, ctor, cdata, pa);
			}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if (a.Target == AttributeTargets.Field) {
				backing_field.ApplyAttributeBuilder (a, ctor, cdata, pa);
				return;
			}

			if (a.Target == AttributeTargets.Method) {
				int errors = Report.Errors;
				Add.ApplyAttributeBuilder (a, ctor, cdata, pa);
				if (errors == Report.Errors)
					Remove.ApplyAttributeBuilder (a, ctor, cdata, pa);
				return;
			}

			base.ApplyAttributeBuilder (a, ctor, cdata, pa);
		}
			public virtual MethodBuilder Define (TypeContainer parent)
			{
				// Fill in already resolved event type to speed things up and
				// avoid confusing duplicate errors
				((Parameter) parameters.FixedParameters[0]).Type = method.member_type;
				parameters.Types = new TypeSpec[] { method.member_type };

				method_data = new MethodData (method, method.ModFlags,
					method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this);

				if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
					return null;

				if (Compiler.Settings.WriteMetadataOnly)
					block = null;

				MethodBuilder mb = method_data.MethodBuilder;

				Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, mb, ParameterInfo, method.ModFlags);
				Spec.IsAccessor = true;

				return mb;
			}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			throw new NotSupportedException ();
		}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if ((a.HasSecurityAttribute)) {
				a.Error_InvalidSecurityParent ();
				return;
			}

			EventBuilder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), cdata);
		}
		//
		// Factory method: if there are pending implementation methods, we return a PendingImplementation
		// object, otherwise we return null.
		//
		// Register method implementations are either abstract methods
		// flagged as such on the base class or interface methods
		//
		static public PendingImplementation GetPendingImplementations (TypeDefinition container)
		{
			TypeSpec b = container.BaseType;

			var missing_interfaces = GetMissingInterfaces (container);

			//
			// If we are implementing an abstract class, and we are not
			// ourselves abstract, and there are abstract methods (C# allows
			// abstract classes that have no abstract methods), then allocate
			// one slot.
			//
			// We also pre-compute the methods.
			//
			bool implementing_abstract = ((b != null) && b.IsAbstract && (container.ModFlags & Modifiers.ABSTRACT) == 0);
			MethodSpec[] abstract_methods = null;

			if (implementing_abstract){
				var am = MemberCache.GetNotImplementedAbstractMethods (b);

				if (am == null) {
					implementing_abstract = false;
				} else {
					abstract_methods = new MethodSpec[am.Count];
					am.CopyTo (abstract_methods, 0);
				}
			}
			
			int total = missing_interfaces.Length +  (implementing_abstract ? 1 : 0);
			if (total == 0)
				return null;

			var pending = new PendingImplementation (container, missing_interfaces, abstract_methods, total);

			//
			// check for inherited conflicting methods
			//
			foreach (var p in pending.pending_implementations) {
				//
				// It can happen for generic interfaces only
				//
				if (!p.type.IsGeneric)
					continue;

				//
				// CLR does not distinguishes between ref and out
				//
				for (int i = 0; i < p.methods.Count; ++i) {
					MethodSpec compared_method = p.methods[i];
					if (compared_method.Parameters.IsEmpty)
						continue;

					for (int ii = i + 1; ii < p.methods.Count; ++ii) {
						MethodSpec tested_method = p.methods[ii];
						if (compared_method.Name != tested_method.Name)
							continue;

						if (p.type != tested_method.DeclaringType)
							continue;

						if (!TypeSpecComparer.Override.IsSame (compared_method.Parameters.Types, tested_method.Parameters.Types))
							continue;

						bool exact_match = true;
						bool ref_only_difference = false;
						var cp = compared_method.Parameters.FixedParameters;
						var tp = tested_method.Parameters.FixedParameters;

						for (int pi = 0; pi < cp.Length; ++pi) {
							//
							// First check exact modifiers match
							//
							if ((cp[pi].ModFlags & Parameter.Modifier.RefOutMask) == (tp[pi].ModFlags & Parameter.Modifier.RefOutMask))
								continue;

							if (((cp[pi].ModFlags | tp[pi].ModFlags) & Parameter.Modifier.RefOutMask) == Parameter.Modifier.RefOutMask) {
								ref_only_difference = true;
								continue;
							}

							exact_match = false;
							break;
						}

						if (!exact_match || !ref_only_difference)
							continue;

						pending.Report.SymbolRelatedToPreviousError (compared_method);
						pending.Report.SymbolRelatedToPreviousError (tested_method);
						pending.Report.Error (767, container.Location,
							"Cannot implement interface `{0}' with the specified type parameters because it causes method `{1}' to differ on parameter modifiers only",
							p.type.GetDefinition().GetSignatureForError (), compared_method.GetSignatureForError ());

						break;
					}
				}
			}

			return pending;
		}
		public EventSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec eventType, Modifiers modifiers, MethodSpec add, MethodSpec remove)
			: base (MemberKind.Event, declaringType, definition, modifiers)
		{
			this.AccessorAdd = add;
			this.AccessorRemove = remove;
			this.MemberType = eventType;
		}
		public void ImplementMethod (MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one, out MethodSpec ambiguousCandidate, ref bool optional)
		{
			InterfaceMethod (name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll, out ambiguousCandidate, ref optional);
		}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if (a.Type == pa.IndexerName) {
				// Attribute was copied to container
				return;
			}

			base.ApplyAttributeBuilder (a, ctor, cdata, pa);
		}
		/// <summary>
		///   C# allows this kind of scenarios:
		///   interface I { void M (); }
		///   class X { public void M (); }
		///   class Y : X, I { }
		///
		///   For that case, we create an explicit implementation function
		///   I.M in Y.
		/// </summary>
		void DefineProxy (TypeSpec iface, MethodSpec base_method, MethodSpec iface_method)
		{
			// TODO: Handle nested iface names
			string proxy_name;
			var ns = iface.MemberDefinition.Namespace;
			if (string.IsNullOrEmpty (ns))
				proxy_name = iface.MemberDefinition.Name + "." + iface_method.Name;
			else
				proxy_name = ns + "." + iface.MemberDefinition.Name + "." + iface_method.Name;

			var param = iface_method.Parameters;

			MethodBuilder proxy = container.TypeBuilder.DefineMethod (
				proxy_name,
				MethodAttributes.Private |
				MethodAttributes.HideBySig |
				MethodAttributes.NewSlot |
				MethodAttributes.CheckAccessOnOverride |
				MethodAttributes.Virtual | MethodAttributes.Final,
				CallingConventions.Standard | CallingConventions.HasThis,
				base_method.ReturnType.GetMetaInfo (), param.GetMetaInfo ());

			if (iface_method.IsGeneric) {
				var gnames = iface_method.GenericDefinition.TypeParameters.Select (l => l.Name).ToArray ();
				proxy.DefineGenericParameters (gnames);
			}

			for (int i = 0; i < param.Count; i++) {
				string name = param.FixedParameters [i].Name;
				ParameterAttributes attr = ParametersCompiled.GetParameterAttribute (param.FixedParameters [i].ModFlags);
				proxy.DefineParameter (i + 1, attr, name);
			}

			int top = param.Count;
			var ec = new EmitContext (new ProxyMethodContext (container), proxy.GetILGenerator (), null, null);
			ec.EmitThis ();
			// TODO: GetAllParametersArguments
			for (int i = 0; i < top; i++)
				ec.EmitArgumentLoad (i);

			ec.Emit (OpCodes.Call, base_method);
			ec.Emit (OpCodes.Ret);

			container.TypeBuilder.DefineMethodOverride (proxy, (MethodInfo) iface_method.GetMetaInfo ());
		}
			protected override void ApplyToExtraTarget (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
			{
				if (a.Target == AttributeTargets.Parameter) {
					parameters[0].ApplyAttributeBuilder (a, ctor, cdata, pa);
					return;
				}

				base.ApplyAttributeBuilder (a, ctor, cdata, pa);
			}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if (a.Type == pa.In && ModFlags == Modifier.OUT) {
				a.Report.Error (36, a.Location, "An out parameter cannot have the `In' attribute");
				return;
			}

			if (a.Type == pa.ParamArray) {
				a.Report.Error (674, a.Location, "Do not use `System.ParamArrayAttribute'. Use the `params' keyword instead");
				return;
			}

			if (a.Type == pa.Out && (ModFlags & Modifier.REF) != 0 &&
			    !OptAttributes.Contains (pa.In)) {
				a.Report.Error (662, a.Location,
					"Cannot specify only `Out' attribute on a ref parameter. Use both `In' and `Out' attributes or neither");
				return;
			}

			if (a.Type == pa.CLSCompliant) {
				a.Report.Warning (3022, 1, a.Location, "CLSCompliant attribute has no meaning when applied to parameters. Try putting it on the method instead");
			} else if (a.Type == pa.DefaultParameterValue || a.Type == pa.OptionalParameter) {
				if (HasOptionalExpression) {
					a.Report.Error (1745, a.Location,
						"Cannot specify `{0}' attribute on optional parameter `{1}'",
						TypeManager.CSharpName (a.Type).Replace ("Attribute", ""), Name);
				}

				if (a.Type == pa.DefaultParameterValue)
					return;
			} else if (a.Type == pa.CallerMemberNameAttribute) {
				if ((modFlags & Modifier.CallerMemberName) == 0) {
					a.Report.Error (4022, a.Location,
						"The CallerMemberName attribute can only be applied to parameters with default value");
				}
			} else if (a.Type == pa.CallerLineNumberAttribute) {
				if ((modFlags & Modifier.CallerLineNumber) == 0) {
					a.Report.Error (4020, a.Location,
						"The CallerLineNumber attribute can only be applied to parameters with default value");
				}
			} else if (a.Type == pa.CallerFilePathAttribute) {
				if ((modFlags & Modifier.CallerFilePath) == 0) {
					a.Report.Error (4021, a.Location,
						"The CallerFilePath attribute can only be applied to parameters with default value");
				}
			}

			base.ApplyAttributeBuilder (a, ctor, cdata, pa);
		}
			public override MethodBuilder Define (TypeContainer parent)
			{
				parameters.Resolve (this);
				
				base.Define (parent);

				Spec = new MethodSpec (MemberKind.Method, parent.PartialContainer.Definition, this, ReturnType, null, ParameterInfo, ModFlags);

				method_data = new MethodData (method, ModFlags, flags, this);

				if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName)))
					return null;

				Spec.SetMetaInfo (method_data.MethodBuilder);

				return method_data.MethodBuilder;
			}
		public override void ApplyAttributeBuilder (Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
		{
			if (a.Type == pa.CLSCompliant) {
				method.Compiler.Report.Warning (3023, 1, a.Location,
					"CLSCompliant attribute has no meaning when applied to return types. Try putting it on the method instead");
			}

			// This occurs after Warning -28
			if (builder == null)
				return;

			base.ApplyAttributeBuilder (a, ctor, cdata, pa);
		}
		//
		// Creates the ConstructorBuilder
		//
		public override bool Define ()
		{
			if (ConstructorBuilder != null)
				return true;

			if (!CheckAbstractAndExtern (block != null))
				return false;
			
			// Check if arguments were correct.
			if (!CheckBase ())
				return false;

			var ca = ModifiersExtensions.MethodAttr (ModFlags) | MethodAttributes.RTSpecialName | MethodAttributes.SpecialName;

			ConstructorBuilder = Parent.TypeBuilder.DefineConstructor (
				ca, CallingConventions,
				parameters.GetMetaInfo ());

			spec = new MethodSpec (MemberKind.Constructor, Parent.Definition, this, Compiler.BuiltinTypes.Void, ConstructorBuilder, parameters, ModFlags);
			
			Parent.MemberCache.AddMember (spec);
			
			if (block != null) {
				// It's here only to report an error
				if (block.IsIterator) {
					member_type = Compiler.BuiltinTypes.Void;
					Iterator.CreateIterator (this, Parent.PartialContainer, ModFlags);
				}

				if (Compiler.Settings.WriteMetadataOnly)
					block = null;
			}

			return true;
		}