public RuleResult CheckMethod (MethodDefinition method)
		{
			// rule only applies to indexers
			if (method.Name != "get_Item")
				return RuleResult.DoesNotApply;

			// ok if the method is not visible outside the assembly
			if (!method.IsVisible ())
				return RuleResult.Success;

			foreach (ParameterDefinition parameter in method.Parameters) {
				TypeReference ptype = parameter.ParameterType;
				bool ok = (ptype.Namespace == "System");
				if (ok) {
					switch (ptype.Name) {
					case "Int32":
					case "Int64":
					case "String":
					case "Object": // tolerable in some circumstances
						break;
					default:
						ok = false;
						break;
					}
				}
				if (!ok)
					Runner.Report (parameter, Severity.Medium, Confidence.Total);
			}
			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			// rule only applies to indexers
			if (method.Name != "get_Item")
				return RuleResult.DoesNotApply;

			// if there is a single argument or if the method is not visible outside the assembly
			if ((method.HasParameters && (method.Parameters.Count == 1)) || !method.IsVisible ())
				return RuleResult.Success;

			Runner.Report (method, Severity.Medium, Confidence.Total);
			return RuleResult.Failure;
		}
        public RuleResult CheckMethod(MethodDefinition method)
        {
            // rule does not apply to non-p/invoke
            if (!method.IsPInvokeImpl)
                return RuleResult.DoesNotApply;

            // rule applies

            // code is very unlikely to work (because of the extra this parameter)
            // note: existing C# compilers won't compile instance p/invoke, e.g.
            // error CS0601: The DllImport attribute must be specified on a method marked `static' and `extern'
            if (!method.IsStatic)
                Runner.Report (method, Severity.Critical, Confidence.Total);

            // code will work (low) but it's bad design (non-fx-like validations) and makes
            // it easier to expose security vulnerabilities
            if (method.IsVisible ())
                Runner.Report (method, Severity.Low, Confidence.Total);

            return Runner.CurrentRuleResult;
        }
		public RuleResult CheckMethod (MethodDefinition method)
		{
			// note: using anonymous methods creates a lot of defects but they are all non-visible
			if (!method.IsVisible ())
				return RuleResult.DoesNotApply;

			MethodReturnType return_type = method.MethodReturnType;
			Severity? severity = Check (return_type.ReturnType);
			if (severity.HasValue)
				Runner.Report (return_type, severity.Value, Confidence.Total);

			if (method.HasParameters) {
				foreach (ParameterDefinition parameter in method.Parameters) {
					severity = Check (parameter.ParameterType);
					if (severity.HasValue)
						Runner.Report (parameter, severity.Value, Confidence.Total);
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			// rule only applies to visible methods with parameters
			// we also exclude all p/invokes since we have a rule for them not to be visible
			if (method.IsPInvokeImpl || !method.HasParameters || !method.IsVisible ())
				return RuleResult.DoesNotApply;

			foreach (ParameterDefinition parameter in method.Parameters) {
				string how = null;
				if (parameter.IsOut) {
					// out is permitted for the "bool Try* (...)" pattern
					if ((method.ReturnType.FullName == "System.Boolean") && 
						method.Name.StartsWith ("Try", StringComparison.Ordinal)) {
						continue;
					}

					how = "out";
				} else if (parameter.IsRef ()) {
					how = "ref";
				}

				if (how != null) {
					// goal is to keep the API as simple as possible so this is more severe for public than protected methods
					Severity severity = method.IsPublic ? Severity.Medium : Severity.Low;
					string msg = String.Format ("Parameter '{0}' passed by reference ({1}).", parameter.Name, how);
					Runner.Report (parameter, severity, Confidence.Total, msg);
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			//does not apply if method has no parameter, is a property, or a p/invoke
			if (!method.HasParameters || method.IsProperty () || method.IsPInvokeImpl)
				return RuleResult.DoesNotApply;

			//if this is a constructor or override, the method name is dependent
			if (method.IsConstructor || method.IsOverride ())
				return RuleResult.DoesNotApply;

			ParameterDefinition p0 = method.Parameters [0];
			string name = p0.ParameterType.Name;

			//param is out/ref, it is already not obvious (there is a rule for that)
			if (p0.IsOut || p0.IsRef ())
				return RuleResult.DoesNotApply;

			string method_name = method.Name;
			if (name.Length == 1 || method_name.Length <= name.Length)
				return RuleResult.DoesNotApply;
			if ((method_name.Length - name.Length) < 4 && IsVaguePrefix (method_name)) //suggestion would be too vague anyway (Get/Set/Is)
				return RuleResult.DoesNotApply;
			if (!char.IsUpper (name [0])) //non-compliant naming, cannot go further (PascalWords needed)
				return RuleResult.DoesNotApply;

			//if the method return the parameter type it is most likely clearer to have it in the name
			if (method.ReturnType == p0.ParameterType)
				return RuleResult.Success;

			//if starting with name it is most likely on purpose
			if (method_name.StartsWith (name, StringComparison.Ordinal))
				return RuleResult.Success;

			int pos = method_name.LastIndexOf (name);
			if (-1 == pos)
				return RuleResult.Success;

			Confidence confidence = Confidence.Normal;
			if (pos >= method_name.Length - name.Length) //suffix, most common and most verbose case
				confidence = Confidence.High;
			else if (!char.IsUpper (method_name [pos + name.Length])) //not the end of a 'PascalWord'
				return RuleResult.Success;

			//if IgnoreAlienNamespaces is True, then check if parameter type is from one of the analyzed namespaces
			if (IgnoreAlienNamespaces && IsTypeFromAlienNamespace (p0.ParameterType))
				return RuleResult.Success; //ignored/out-of-reach, so this is a success

			//main goal is to keep the API as simple as possible so this is more severe for visible methods
			Severity severity = method.IsVisible () ? Severity.Medium : Severity.Low;

			string suggestion = GetSuggestionMethodName (method, name, pos);
			string msg;
			if (method.IsStatic) { //we already have a rule that checks if the method should be static
				string memberKind = GetSuggestionMemberKind (method);
				msg = String.Format ("Consider renaming method to '{2}', or extracting method to type '{0}' as {1} '{2}', or making an extension method of that type.", 
					p0.ParameterType, memberKind, suggestion);
			} else {
				msg = String.Format ("Consider renaming method to '{0}'.", suggestion);
			}

			Runner.Report (method, severity, confidence, msg);
			return RuleResult.Failure;
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			// p/invoke, abstract methods and method without parameters
			if (!method.HasBody || !method.HasParameters || !method.IsVisible ())
				return RuleResult.DoesNotApply;

			has_null_check.ClearAll ();
			int parameters = method.Parameters.Count;

			// check
			foreach (Instruction ins in method.Body.Instructions) {
				if (ins.IsLoadArgument ()) {
					CheckArgument (method, ins);
				} else if (OpCodeBitmask.Calls.Get (ins.OpCode.Code)) {
					CheckCall (method, ins);
				} else if (check.Get (ins.OpCode.Code)) {
					Instruction owner = ins;
					// fields (no need to check static fields), ldind, ldelem, ldlen
					while ((owner != null) && check.Get (owner.OpCode.Code)) {
						owner = owner.TraceBack (method);
					}
					CheckParameter (owner.GetParameter (method));
				}

				// stop processing instructions once all parameters are validated
				if (has_null_check.Count () == parameters)
					break;
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			// methods using vararg are easily identifiable
			if ((method.CallingConvention & MethodCallingConvention.VarArg) == 0)
				return RuleResult.Success;

			// __arglist is accepted for interoperability purpose
			if (method.IsPInvokeImpl)
				return RuleResult.Success;

			// all other case should be changed to use "params"
			// this is more severe for visible methods since vararg is not CLS compliant
			Severity severity = method.IsVisible () ? Severity.Critical : Severity.High;
			Runner.Report (method, severity, Confidence.High);
			return RuleResult.Failure;
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			// check if the the rule applies to this method
			if (!Applicable (method))
				return RuleResult.DoesNotApply;

			// we can't be sure if this code won't be reached indirectly
			if (method.IsVirtual && !method.IsFinal)
				return RuleResult.Success;

			// if the method is visible outside the assembly
			if (method.IsVisible ())
				return RuleResult.Success;

			// check if the method is private 
			if (method.IsPrivate) {
				if (!CheckPrivateMethod (method)) {
					Runner.Report (method, Severity.High, Confidence.Normal, "The private method code is not used in its declaring type.");
					return RuleResult.Failure;
				}
				return RuleResult.Success;
			}

			if (method.IsPublic && CheckPublicMethod (method))
				return RuleResult.Success;

			if (method.IsAssembly && CheckInternalMethod (method))
				return RuleResult.Success;

			// internal methods and visible methods (public or protected) inside a non-visible type
			// needs to be checked if something in the assembly is using this method
			bool need_to_check_assembly = (method.IsAssembly || 
				((method.IsPublic || method.IsFamily) && !method.DeclaringType.IsVisible ()));

			if (!need_to_check_assembly || CheckAssemblyForMethodUsage (method))
				return RuleResult.Success;

			// method is unused and unneeded
			Runner.Report (method, Severity.High, Confidence.Normal, "The method is not visible outside its declaring assembly, nor used within.");
			return RuleResult.Failure;
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			// #1 - rule apply only if the method has a body (e.g. p/invokes, icalls don't)
			//	otherwise we don't know what it's calling
			if (!method.HasBody)
				return RuleResult.DoesNotApply;
			
			// #2 - rule apply to methods are publicly accessible
			//	note that the type doesn't have to be public (indirect access)
			if (!method.IsVisible ())
				return RuleResult.DoesNotApply;

			// #3 - avoid looping if we're sure there's no call in the method
			if (!OpCodeBitmask.Calls.Intersect (OpCodeEngine.GetBitmask (method)))
				return RuleResult.DoesNotApply;

			// *** ok, the rule applies! ***

			// #4 - look for every method we call
			foreach (Instruction ins in method.Body.Instructions) {
				switch (ins.OpCode.Code) {
				case Code.Call:
				case Code.Callvirt:
					MethodDefinition callee = (ins.Operand as MethodDefinition);
					if (callee == null)
						continue;

					// 4 - and if it has security, ensure we don't reduce it's strength
					if (callee.HasSecurityDeclarations && !Check (method, callee)) {
						Runner.Report (method, ins, Severity.High, Confidence.High);
					}
					break;
				}
			}
			return Runner.CurrentRuleResult;
		}
		private void CheckMethod (MethodDefinition method)
		{
			// Getters/setters handled by CheckProperty.
			if (method.IsGetter || method.IsSetter || !method.IsVisible ())
				return;
			if (IsList (method.ReturnType))
				Runner.Report (method, Severity.Medium, Confidence.Total);
			if (!method.HasParameters)
				return;
			foreach (var param in method.Parameters) {
				if (IsList (param.ParameterType))
					Runner.Report (param, Severity.Medium, Confidence.Total);
			}
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			if (!method.IsVisible ())
				return RuleResult.DoesNotApply;

			MethodReturnType mrt = method.MethodReturnType;
			if (IsSpecificXmlType (mrt.ReturnType))
				Runner.Report (mrt, GetSeverity (method), Confidence.High);

			if (method.HasParameters) {
				foreach (ParameterDefinition parameter in method.Parameters) {
					if (parameter.IsOut)
						continue; //out params already have their rule

					if (IsSpecificXmlType (parameter.ParameterType))
						Runner.Report (parameter, GetSeverity (method), Confidence.High);
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			// exclude constrcutors, non-visible methods and generated code
			if (method.IsConstructor || !method.IsVisible () || method.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			// the rule does not apply if the code is an interface to COM objects
			if (UsedForComInterop (method.DeclaringType as TypeDefinition))
				return RuleResult.DoesNotApply;

			// check the method name
			if (!CheckName (method.Name, method.IsSpecialName))
				Runner.Report (method, Severity.Medium, Confidence.High);

			if (method.HasParameters) {
				foreach (ParameterDefinition parameter in method.Parameters) {
					if (!CheckName (parameter.Name, false))
						Runner.Report (parameter, Severity.Medium, Confidence.High);
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			CheckIdentifier (method, method.Name, method.IsVisible () ? Severity.Medium : Severity.Low);
			// we're not checking parameters
			return Runner.CurrentRuleResult;
		}
		protected override void Report (MethodDefinition method, Instruction ins)
		{
			string msg = string.Format ("Replace null with {0}.", SuggestReturnType ());
			Runner.Report (method, ins, method.IsVisible () ? Severity.Medium : Severity.Low, Confidence.Normal, msg);
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			if (!method.IsSynchronized)
				return RuleResult.Success;

			// special case since the compiler generate add/remove on events using Synchronized
			if (method.IsAddOn || method.IsRemoveOn)
				return RuleResult.DoesNotApply;

			// base severity on whether the method is visible or not
			// if not then the potential problem is limited to the assembly
			Severity severity = method.IsVisible () ? Severity.High : Severity.Medium;
			Runner.Report (method, severity, Confidence.Total);
			return RuleResult.Failure;
		}