public RuleResult CheckMethod (MethodDefinition method)
		{
			// we only check non static, non virtual methods and not constructors
			if (method.IsStatic || method.IsVirtual || method.IsConstructor)
				return RuleResult.DoesNotApply;

			// we only check methods with a body
			if (!method.HasBody)
				return RuleResult.DoesNotApply;

			// we also don't check event callbacks, as they usually bring a lot of false positive,
			// and that developers are tied to their signature
			if (method.IsEventCallback ())
				return RuleResult.DoesNotApply;

			// that aren't compiler generated (e.g. anonymous methods) or generated by a tool (e.g. web services)
			if (method.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			// methods with [Conditional] can be empty (not using 'this') IL-wise but not source-wise, ignore them
			if (method.HasCustomAttributes) {
				if (method.HasAttribute ("System.Diagnostics", "ConditionalAttribute"))
					return RuleResult.DoesNotApply;
			}

			// rule applies

			// if we find a use of the "this" reference, it's ok

			// in most (all?) case "this" is used with the ldarg_0 instruction
			if (OpCodeEngine.GetBitmask (method).Get (Code.Ldarg_0))
				return RuleResult.Success;

			// but it's also valid to have an ldarg with a 0 value operand
			foreach (Instruction instr in method.Body.Instructions) {
				if (instr.OpCode.Code == Code.Ldarg) {
					ParameterDefinition pd = (instr.Operand as ParameterDefinition);
					if (pd.Index == -1)
						return RuleResult.Success;
				}
			}

			Runner.Report (method, Severity.Low, Confidence.Total);
			return RuleResult.Failure;
		}
        // Method		Visible		Non-Visible
        // ------------------------------------------------
        // Parameters		High		Medium
        // ReturnType		High		Medium
        // Variables		Low		Low
        // Method calls		Medium*		Low*
        // Fields access	Medium*		Low*
        // * target visibility
        public RuleResult CheckMethod(MethodDefinition method)
        {
            // [Obsolete] cannot be applied to property or event accessors
            if (method.IsProperty () || method.IsAddOn || method.IsRemoveOn || method.IsFire)
                return RuleResult.DoesNotApply;

            // if the method is obsolete (directly or because it's type is)
            if (method.HasAttribute ("System", "ObsoleteAttribute") || method.DeclaringType.HasAttribute ("System", "ObsoleteAttribute"))
                return RuleResult.DoesNotApply;

            // check method signature (parameters, return value)
            if (method.HasParameters)
                CheckParameters (method);

            CheckReturnType (method);

            // then check what the IL calls/access
            if (method.HasBody) {
                MethodBody body = method.Body;
                if (body.HasVariables)
                    CheckVariables (method);

                foreach (Instruction ins in body.Instructions) {
                    switch (ins.OpCode.Code) {
                    case Code.Newarr:
                    case Code.Newobj:
                    case Code.Call:
                    case Code.Callvirt:
                        CheckMethodCall (method, ins, (ins.Operand as MethodReference));
                        break;
                    case Code.Initobj:
                        CheckTypeCreation (method, ins, (ins.Operand as TypeReference));
                        break;
                    case Code.Ldfld:
                    case Code.Ldflda:
                    case Code.Ldsfld:
                    case Code.Ldsflda:
                    case Code.Stfld:
                    case Code.Stsfld:
                        CheckFieldAccess (method, ins, (ins.Operand as FieldReference));
                        break;
                    }
                }
            }

            return Runner.CurrentRuleResult;
        }
		public RuleResult CheckMethod (MethodDefinition method)
		{
			if (!method.HasAttribute (SUCS))
				return RuleResult.Success;

			Runner.Report (method, Severity.Audit, Confidence.Total);
			return RuleResult.Failure;
		}
        public RuleResult CheckMethod(MethodDefinition method)
        {
            // catch abstract, pinvoke and icalls - where rule does not apply
            if (!method.HasBody)
                return RuleResult.DoesNotApply;

            // skip methods without parameters
            if (!method.HasParameters)
                return RuleResult.DoesNotApply;

            // rule doesn't apply to virtual, overrides or generated code
            // doesn't apply to code referenced by delegates (note: more complex check moved last)
            if (method.IsVirtual || method.HasOverrides || method.IsGeneratedCode ())
                return RuleResult.DoesNotApply;

            // Also EventArgs parameters are often required in method signatures,
            // but often not required. Reduce "false positives"(*) for GUI apps
            // (*) it's more a "don't report things outside developer's control"
            if (method.IsEventCallback () || IsReferencedByDelegate (method))
                return RuleResult.DoesNotApply;

            // methods with [Conditional] can be empty (not using any parameter) IL-wise but not source-wise, ignore them
            if (method.HasAttribute ("System.Diagnostics", "ConditionalAttribute"))
                return RuleResult.DoesNotApply;

            // rule applies

            // we limit ourselves to the first 64 parameters (so we can use a bitmask)
            IList<ParameterDefinition> pdc = method.Parameters;
            int pcount = pdc.Count;
            if (pcount > 64)
                pcount = 64;
            ulong mask = 0;

            // scan IL to see which parameter is being used
            foreach (Instruction ins in method.Body.Instructions) {
                ParameterDefinition parameter = ins.GetParameter (method);
                if (parameter == null)
                    continue;
                mask |= ((ulong)1 << parameter.Index);
            }

            // quick out based on value - i.e. every parameter is being used
            int shift = 64 - pcount;
            if ((mask << shift) == (UInt64.MaxValue << shift))
                return RuleResult.Success;

            for (int i = 0; i < pcount; i++) {
                if ((mask & ((ulong) 1 << i)) == 0) {
                    ParameterDefinition parameter = pdc [i];
                    string text = String.Format (CultureInfo.InvariantCulture,
                        "Parameter '{0}' of type '{1}' is never used in the method.",
                        parameter.Name, parameter.ParameterType);
                    Runner.Report (parameter, Severity.Medium, Confidence.Normal, text);
                }
            }

            return Runner.CurrentRuleResult;
        }
		// rock-ify
		// not 100% bullet-proof against buggy compilers (or IL)
		static bool IsExtension (MethodDefinition method)
		{
			if (!method.IsStatic)
				return false;

			if (!method.HasParameters)
				return false;

			return method.HasAttribute ("System.Runtime.CompilerServices.ExtensionAttribute");
		}
		public RuleResult CheckMethod (MethodDefinition method)
		{
			if (!method.HasAttribute ("System.Security", "SuppressUnmanagedCodeSecurityAttribute"))
				return RuleResult.Success;

			Runner.Report (method, Severity.Audit, Confidence.Total);
			return RuleResult.Failure;
		}