public RuleResult CheckType (TypeDefinition type)
		{
			// rule applies only to types, interfaces and structures (value types)
			if (type.IsEnum || type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			// rule onyly applies to type that implements IDisposable
			if (!type.Implements ("System.IDisposable"))
				return RuleResult.DoesNotApply;

			// no problem is a finalizer is found
			if (type.HasMethod (MethodSignatures.Finalize))
				return RuleResult.Success;

			// otherwise check for native types
			foreach (FieldDefinition field in type.Fields) {
				// we can't dispose static fields in IDisposable
				if (field.IsStatic)
					continue;
				if (!field.FieldType.GetElementType ().IsNative ())
					continue;
				Runner.Report (field, Severity.High, Confidence.High);
			}

			// special case: a struct cannot define a finalizer so it's a
			// bad candidate to hold references to unmanaged resources
			if (type.IsValueType && (Runner.CurrentRuleResult == RuleResult.Failure))
				Runner.Report (type, Severity.High, Confidence.High, Struct);

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			if (type.IsEnum || type.IsInterface || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			MethodDefinition equality = type.GetMethod (MethodSignatures.op_Equality);
			if ((equality == null) || type.HasMethod (MethodSignatures.Equals))
				return RuleResult.Success;
			
			Runner.Report (equality, Severity.High, Confidence.High);
			return RuleResult.Failure;
		}
        public RuleResult CheckType(TypeDefinition type)
        {
            // rule applies only to ValueType, except enums and generated code
            if (!type.IsValueType || type.IsEnum || type.IsGeneratedCode ())
                return RuleResult.DoesNotApply;

            // note: no inheritance check required since we're dealing with structs

            bool equals = type.HasMethod (MethodSignatures.Equals);
            bool gethashcode = type.HasMethod (MethodSignatures.GetHashCode);
            bool operators = type.HasMethod (MethodSignatures.op_Equality) &&
                type.HasMethod (MethodSignatures.op_Inequality);

            // note: we want to avoid reporting 4 defects each (well most) of the time
            // the rule is triggered (it's too verbose to be useful)
            if (equals && gethashcode && operators)
                return RuleResult.Success;

            // drop severity one level if only operators are missing (since overloading them
            // is not available in every language)
            Severity severity = (equals || gethashcode) ? Severity.Medium : Severity.Low;
            string msg = String.Format (CultureInfo.InvariantCulture, MissingImplementationMessage,
                !equals && !gethashcode ? "Equals(object)' and 'GetHashCode()" : equals ? "GetHashCode()" : "Equals(object)",
                operators ? String.Empty : MissingOperatorsMessage);

            Runner.Report (type, severity, Confidence.High, msg);
            return RuleResult.Failure;
        }
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule does not apply to enums, delegates and to generated code
			if (type.IsEnum || type.IsDelegate () || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			// rule applies only if the type overrides Equals(object)
			if (!type.HasMethod (MethodSignatures.Equals))
				return RuleResult.DoesNotApply;

			// if so then the type should also implement Equals(type) since this avoid a cast 
			// operation (for reference types) and also boxing (for value types).

			// we suggest to implement IEquatable<T> if
			// * the assembly targets the 2.0 (or later) runtime
			// * and it does not already implement it
			if (type.Module.Runtime >= TargetRuntime.Net_2_0) {
				if (!type.Implements ("System", "IEquatable`1")) {
					Runner.Report (type, Severity.Medium, Confidence.Total, "Implement System.IEquatable<T>");
				}
				return Runner.CurrentRuleResult;
			}

			parameters [0] = type.GetFullName ();
			if (type.GetMethod (MethodAttributes.Public, "Equals", "System.Boolean", parameters) != null)
				return RuleResult.Success;

			// we consider this a step more severe for value types since it will need 
			// boxing/unboxing with Equals(object)
			Severity severity = type.IsValueType ? Severity.Medium : Severity.Low;
			string msg = String.Format (CultureInfo.InvariantCulture, "Implement 'bool Equals({0})'", type.Name);
			Runner.Report (type, severity, Confidence.High, msg);
			return RuleResult.Failure;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule doesn't apply to interfaces and enums
			if (type.IsInterface || type.IsEnum || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			bool equals = type.HasMethod (MethodSignatures.Equals);
			bool getHashCode = type.HasMethod (MethodSignatures.GetHashCode);

			// if we have Equals but no GetHashCode method
			if (equals && !getHashCode) {
				string text = String.Format (Message, MethodSignatures.Equals, MethodSignatures.GetHashCode);
				Runner.Report (type, Severity.Critical, Confidence.High, text);
			}

			// if we have GetHashCode but no Equals method
			if (!equals && getHashCode) {
				string text = String.Format (Message, MethodSignatures.GetHashCode, MethodSignatures.Equals);
				Runner.Report (type, Severity.Medium, Confidence.High, text);
			}

			// we either have both Equals and GetHashCode or none (both fine)
			return Runner.CurrentRuleResult;
		}
        public RuleResult CheckType(TypeDefinition type)
        {
            // rule applies only to types and interfaces
            if (type.IsEnum || type.IsDelegate() || type.IsGeneratedCode() ||
                type.IsValueType || type.IsInterface)
                return RuleResult.DoesNotApply;

            // rule only applies to type that implements IDisposable
            if (!type.Implements("System", "IDisposable"))
                return RuleResult.DoesNotApply;

            // rule only applies to type that doesn't derive from class that implements IDisposable
            if (type.BaseType.Implements("System", "IDisposable"))
                return RuleResult.DoesNotApply;

            // rule only applies if type has a Dispose(bool) method
            if (!type.HasMethod(Dispose))
                return RuleResult.DoesNotApply;

            // no problem if a finalizer is found
            if (type.HasMethod(MethodSignatures.Finalize))
                return RuleResult.Success;

            Runner.Report(type, Severity.Medium, Confidence.High);
            return RuleResult.Failure;
        }
		public RuleResult CheckType (TypeDefinition type)
		{
			if (type.IsEnum || type.IsInterface || type.IsDelegate ())
				return RuleResult.DoesNotApply;

			if (type.HasMethod (MethodSignatures.op_Addition) && type.HasMethod (MethodSignatures.op_Subtraction)) {
				if (!type.HasMethod (MethodSignatures.op_Equality)) {
					Runner.Report (type, Severity.Low, Confidence.High, "This type implements the addition (+) and subtraction (-) operators. It should also implement the equality (==) operator.");
				}
			}

			if (type.IsValueType) {
				if (type.HasMethod (MethodSignatures.Equals) && !type.HasMethod (MethodSignatures.op_Equality)) {
					Runner.Report (type, Severity.Medium, Confidence.High, "This type overrides Object.Equals. It should also implement the equality (==) operator.");
				}
			}

			return Runner.CurrentRuleResult;
		}
		public RuleResult CheckType (TypeDefinition type)
		{
			// rule does not apply to enums, interfaces and to generated code
			if (type.IsEnum || type.IsInterface || type.IsGeneratedCode ())
				return RuleResult.DoesNotApply;

			// rule only applies if the type implements IComparable or IComparable<T>
			// Note: we do not use Implements rock because we do not want a recursive answer
			bool icomparable = false;
			foreach (TypeReference iface in type.Interfaces) {
				if (iface.Namespace != "System")
					continue;
				// catch both System.IComparable and System.IComparable`1<X>
				if (iface.Name.StartsWith ("IComparable", StringComparison.Ordinal)) {
					icomparable = true;
					break;
				}
			}
			if (!icomparable)
				return RuleResult.DoesNotApply;

			// type should override Equals(object)
			if (!type.HasMethod (MethodSignatures.Equals))
				Runner.Report (type, Severity.High, Confidence.High, "Missing Equals(object) override.");

			// type should implement overloads for ==, !=, < and > operators
			// note: report all missing operators as single defect
			bool equality = type.HasMethod (MethodSignatures.op_Equality);
			bool inequality = type.HasMethod (MethodSignatures.op_Inequality);
			bool less_than = type.HasMethod (MethodSignatures.op_LessThan);
			bool greater_than = type.HasMethod (MethodSignatures.op_GreaterThan);
			if (!equality || !inequality || !less_than || !greater_than) {
				StringBuilder sb = new StringBuilder ("Missing operators:");
				if (!equality)
					sb.Append (" op_Equality (==)");
				if (!inequality)
					sb.Append (" op_Inequality (!=)");
				if (!less_than)
					sb.Append (" op_LessThan (<)");
				if (!greater_than)
					sb.Append (" op_GreaterThan (>)");
				// not all languages support operator overloading so we lower the severity a bit
				Runner.Report (type, Severity.Medium, Confidence.High, sb.ToString ());
			}

			return Runner.CurrentRuleResult;
		}