public static TypeSpec CreateDelegateType (ResolveContext rc, AParametersCollection parameters, TypeSpec returnType, Location loc)
		{
			Namespace type_ns = rc.Module.GlobalRootNamespace.GetNamespace ("System", true);
			if (type_ns == null) {
				return null;
			}
			if (returnType == rc.BuiltinTypes.Void) {
				var actArgs = parameters.Types;
				var actionSpec = type_ns.LookupType (rc.Module, "Action", actArgs.Length, LookupMode.Normal, loc).ResolveAsType(rc);
				if (actionSpec == null) {
					return null;
				}
				if (actArgs.Length == 0)
					return actionSpec;
				else
					return actionSpec.MakeGenericType(rc, actArgs);
			} else {
				TypeSpec[] funcArgs = new TypeSpec[parameters.Types.Length + 1];
				parameters.Types.CopyTo(funcArgs, 0);
				funcArgs[parameters.Types.Length] = returnType;
				var funcSpec = type_ns.LookupType (rc.Module, "Func", funcArgs.Length, LookupMode.Normal, loc).ResolveAsType(rc);
				if (funcSpec == null)
					return null;
				return funcSpec.MakeGenericType(rc, funcArgs);
			}
		}
		//
		// Returns non-zero value for equal CLS parameter signatures
		//
		public static int IsSameClsSignature (AParametersCollection a, AParametersCollection b)
		{
			int res = 0;

			for (int i = 0; i < a.Count; ++i) {
				var a_type = a.Types[i];
				var b_type = b.Types[i];
				if (TypeSpecComparer.Override.IsEqual (a_type, b_type)) {
					if ((a.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask) != (b.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask))
						res |= 1;

					continue;
				}

				var ac_a = a_type as ArrayContainer;
				if (ac_a == null)
					return 0;

				var ac_b = b_type as ArrayContainer;
				if (ac_b == null)
					return 0;

				if (ac_a.Element is ArrayContainer || ac_b.Element is ArrayContainer) {
					res |= 2;
					continue;
				}

				if (ac_a.Rank != ac_b.Rank && TypeSpecComparer.Override.IsEqual (ac_a.Element, ac_b.Element)) {
					res |= 1;
					continue;
				}

				return 0;
			}

			return res;
		}
		public IndexerSpec (TypeSpec declaringType, IMemberDefinition definition, TypeSpec memberType, AParametersCollection parameters, PropertyInfo info, Modifiers modifiers)
			: base (MemberKind.Indexer, declaringType, definition, memberType, info, modifiers)
		{
			this.parameters = parameters;
		}
		public MethodSpec (MemberKind kind, TypeSpec declaringType, IMemberDefinition details, TypeSpec returnType,
			MethodBase info, AParametersCollection parameters, Modifiers modifiers)
			: base (kind, declaringType, details, modifiers)
		{
			this.metaInfo = info;
			this.parameters = parameters;
			this.returnType = returnType;
		}
		public static Arguments CreateDelegateMethodArguments (ResolveContext rc, AParametersCollection pd, TypeSpec[] types, Location loc)
		{
			Arguments delegate_arguments = new Arguments (pd.Count);
			for (int i = 0; i < pd.Count; ++i) {
				Argument.AType atype_modifier;
				switch (pd.FixedParameters [i].ModFlags) {
				case Parameter.Modifier.REF:
					atype_modifier = Argument.AType.Ref;
					break;
				case Parameter.Modifier.OUT:
					atype_modifier = Argument.AType.Out;
					break;
				default:
					atype_modifier = 0;
					break;
				}

				var ptype = types[i];
				if (ptype.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
					ptype = rc.BuiltinTypes.Object;

				delegate_arguments.Add (new Argument (new TypeExpression (ptype, loc), atype_modifier));
			}

			return delegate_arguments;
		}
		public ImportedGenericMethodDefinition (MethodInfo provider, TypeSpec type, AParametersCollection parameters, TypeParameterSpec[] tparams, MetadataImporter importer)
			: base (provider, type, parameters, importer)
		{
			this.tparams = tparams;
		}
		public ImportedParameterMemberDefinition (PropertyInfo provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer)
			: base (provider, type, importer)
		{
			this.parameters = parameters;
		}
		protected bool VerifyParameterCompatibility (ResolveContext ec, TypeSpec delegate_type, AParametersCollection invoke_pd, bool ignore_errors)
		{
			if (Parameters.Count != invoke_pd.Count) {
				if (ignore_errors)
					return false;
				
				ec.Report.Error (1593, loc, "Delegate `{0}' does not take `{1}' arguments",
					      TypeManager.CSharpName (delegate_type), Parameters.Count.ToString ());
				return false;
			}

			bool has_implicit_parameters = !HasExplicitParameters;
			bool error = false;

			for (int i = 0; i < Parameters.Count; ++i) {
				Parameter.Modifier p_mod = invoke_pd.FixedParameters [i].ModFlags;
				if (Parameters.FixedParameters [i].ModFlags != p_mod && p_mod != Parameter.Modifier.PARAMS) {
					if (ignore_errors)
						return false;
					
					if (p_mod == Parameter.Modifier.NONE)
						ec.Report.Error (1677, loc, "Parameter `{0}' should not be declared with the `{1}' keyword",
							      (i + 1).ToString (), Parameter.GetModifierSignature (Parameters.FixedParameters [i].ModFlags));
					else
						ec.Report.Error (1676, loc, "Parameter `{0}' must be declared with the `{1}' keyword",
							      (i+1).ToString (), Parameter.GetModifierSignature (p_mod));
					error = true;
				}

				if (has_implicit_parameters)
					continue;

				TypeSpec type = invoke_pd.Types [i];
				
				// We assume that generic parameters are always inflated
				if (TypeManager.IsGenericParameter (type))
					continue;
				
				if (TypeManager.HasElementType (type) && TypeManager.IsGenericParameter (TypeManager.GetElementType (type)))
					continue;
				
				if (!TypeSpecComparer.IsEqual (invoke_pd.Types [i], Parameters.Types [i])) {
					if (ignore_errors)
						return false;
					
					ec.Report.Error (1678, loc, "Parameter `{0}' is declared as type `{1}' but should be `{2}'",
						      (i+1).ToString (),
						      TypeManager.CSharpName (Parameters.Types [i]),
						      TypeManager.CSharpName (invoke_pd.Types [i]));
					error = true;
				}
			}

			return !error;
		}
		protected bool VerifyExplicitParameters (ResolveContext ec, TypeSpec delegate_type, AParametersCollection parameters)
		{
			if (VerifyParameterCompatibility (ec, delegate_type, parameters, ec.IsInProbingMode))
				return true;

			if (!ec.IsInProbingMode)
				ec.Report.Error (1661, loc,
					"Cannot convert `{0}' to delegate type `{1}' since there is a parameter mismatch",
					GetSignatureForError (), TypeManager.CSharpName (delegate_type));

			return false;
		}