public MessageCollection CheckMethod(MethodDefinition method, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection();

			if (method.Body == null || method.Body.Instructions == null)
			{
				return null;
			}

			foreach (Instruction instruction in method.Body.Instructions)
			{
				if (instruction.OpCode.Code == Code.Pop)
				{
					Message message = CheckForViolation(instruction.Previous);

					if (message != null)
					{
						messageCollection.Add(message);
					}
				}
			}
			

			return messageCollection.Count == 0 ? runner.RuleSuccess : messageCollection;
		}
		public MessageCollection CheckType(TypeDefinition type, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection();

			foreach (MethodDefinition method in type.Methods)
			{
				if (!method.IsStatic)
				{
					return null;
				}
			}

			foreach (FieldDefinition field in type.Fields)
			{
				if (!field.IsStatic)
				{
					return null;
				}
			}
			
			foreach (MethodDefinition ctor in type.Constructors)
			{
				if (!ctor.IsStatic && (ctor.Attributes & MethodAttributes.Public) == MethodAttributes.Public)
				{
					Location location = new Location(type.Name, ctor.Name, 0);
					Message message = new Message(MessageString, location, MessageType.Error);
					messageCollection.Add(message);
				}
			}

			return messageCollection.Count > 0 ? messageCollection : null;
			
		}
		private bool ContainsAvoidUnusedParametersRule (Runner runner)
		{
			foreach (IMethodRule rule in runner.Rules.Method) {
				if (rule is AvoidUnusedParametersRule)
					return true;
			}
			return false;
		}
		public MessageCollection CheckType (TypeDefinition type, Runner runner) 
		{
			messageCollection = new MessageCollection ();
			codeDuplicatedLocator = new CodeDuplicatedLocator ();
			
			ICollection siblingClasses = Utilities.GetInheritedClassesFrom (type);
			if (siblingClasses.Count >= 2) 
				CompareSiblingClasses (siblingClasses);

			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckType (TypeDefinition type, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			
			if (!ImplementsInternalsVisibleToAttribute (type) && (type.GetType ().IsAnsiClass || type.GetType ().IsClass || type.GetType ().IsAutoClass) && type.Name != "<Module>" && IsInstantiable (type) && !IsInstantiated (type, type)) {
				Location location = new Location (type.FullName, type.Name, 0);
				Message message = new Message ("There is no call for any of the types constructor found", location, MessageType.Error);
				messageCollection.Add (message);
			}
			
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition method, Runner runner) 
		{
			MessageCollection messageCollection = new MessageCollection ();
			
			if (HasLongParameterList (method)) {
				Location location = new Location (method.DeclaringType.Name, method.Name, 0);		
				Message message = new Message ("The method contains a long parameter list.",location, MessageType.Error);
				messageCollection.Add (message);
			}

			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckType (TypeDefinition typeDefinition, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			if (InheritsFromAttribute (typeDefinition)) {
				if (!typeDefinition.Name.EndsWith ("Attribute")) {
					Location location = new Location (typeDefinition.FullName, typeDefinition.Name, 0);
					Message message = new Message ("The class name doesn't end with Attribute Suffix", location, MessageType.Error);
					messageCollection.Add (message);                        
				}
			}
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckType (TypeDefinition type, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			if (!ImplementsICloneable (type))
				foreach (MethodDefinition method in type.Methods)
					if (method.Name == "Clone" && method.ReturnType.ReturnType.ToString ().Equals ("System.Object") && method.Parameters.Count == 0) {
						Location location = new Location (type.FullName, type.Name, 0);
						Message message = new Message ("The Clone () method is used, but ICloneable is not implemented", location, MessageType.Error);
						messageCollection.Add (message);
					}
					    
			if (messageCollection.Count == 0)
					return null;
			return messageCollection;
		}
		public MessageCollection CheckType (TypeDefinition typeDefinition, Runner runner) 
		{
			messageCollection = new MessageCollection ();
			CodeDuplicatedLocator codeDuplicatedLocator = new CodeDuplicatedLocator ();
			foreach (MethodDefinition currentMethod in typeDefinition.Methods) {
				foreach (Message message in codeDuplicatedLocator.CompareMethodAgainstTypeMethods (currentMethod, typeDefinition)) {
					messageCollection.Add (message);
				}
				codeDuplicatedLocator.CheckedMethods.Add (currentMethod.Name);
			}
			
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition method, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			TypeDefinition type = method.DeclaringType as TypeDefinition;
			
			if (MemberIsCallable (type, method) && !MemberIsCalled (type, method)) {
				Location location = new Location (method.DeclaringType.FullName, method.Name, 0);
				Message message = new Message ("The private or internal code is not called", location, MessageType.Error);
				messageCollection.Add (message);
			}
			
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition method, Runner runner) 
		{
			MessageCollection messageCollection = new MessageCollection ();
			InitWellKnownAutogeneratedNames ();

			if (MethodIsTooLong (method) && !IsAutogenerated (method)) {
				Location location = new Location (method.DeclaringType.Name, method.Name, 0);		
				Message message = new Message ("The method is too long.",location, MessageType.Error);
				messageCollection.Add (message);
			}

			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckType (TypeDefinition type, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			if (type.IsSealed) {
				foreach (FieldDefinition field in type.Fields) {
					if (field.Attributes.ToString () == "Family") {
						Location location = new Location (type.FullName, type.Name, 0);
						Message message = new Message ("This sealed class contains protected field(s)", location, MessageType.Error);
						messageCollection.Add (message);
					}
				}
			}
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckType (TypeDefinition typeDefinition, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			if (typeDefinition.IsEnum) {
				if (!HasFlagsAttribute (typeDefinition)) {
					if (IsPlural (typeDefinition.Name)) {
						Location location = new Location (typeDefinition.FullName, typeDefinition.Name, 0);
						Message message = new Message ("The enum has a plural name.", location, MessageType.Error);
						messageCollection.Add (message);
					}
				}
			}
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition method, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			
			if (method.HasBody && method.Name == "Equals" && method.ReturnType.ReturnType.ToString () == "System.Boolean" && method.IsVirtual && !method.IsNewSlot)
				foreach (ParameterDefinition param in method.Parameters)
					if (param.ParameterType.FullName == "System.Object")
						if (!HandlesNullArg (method)) {
						Location location = new Location (method.DeclaringType.FullName, method.Name, 0);
						Message message = new Message ("The overridden method Object.Equals (Object) does not return false if null value is found", location, MessageType.Error);
						messageCollection.Add (message);
					}
			
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckType (TypeDefinition type, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			if (ImplementsICloneable (type))
				foreach (MethodDefinition method in type.Methods) 
					if (method.Name == "Clone" && method.Parameters.Count == 0)
						foreach (Instruction instruction in method.Body.Instructions) {
							Instruction prevInstr = instruction.Previous;
							if (instruction.OpCode.Name == "ret" && prevInstr.OpCode.Name == "ldnull") {
								Location location = new Location (type.FullName, type.Name, instruction.Offset);
								Message message = new Message ("The ICloneable.Clone () method returns null", location, MessageType.Error);
								messageCollection.Add (message);
							}
						}
			if (messageCollection.Count == 0)
					return null;
			return messageCollection;
		}
		public MessageCollection CheckType (TypeDefinition type, Runner runner)
		{
			string [] access_spec  = type.Attributes.ToString ().Split(',');
			MessageCollection messageCollection = new MessageCollection ();
			
			// Compiler generates an error for any other non alpha-numerics than underscore ('_'), so we just need to check the presence of underscore in type names 
			
			if (access_spec[0] != "NestedPrivate" && type.Name.IndexOf ("_") != -1)
			{
				Location location = new Location (type.FullName, type.Name, 0);
				Message message = new Message ("Type name contains underscore", location, MessageType.Error);
				messageCollection.Add (message);
			}
			
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod(MethodDefinition method, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection();

			foreach (Instruction instruction in method.Body.Instructions)
			{
				if (instruction.OpCode.Code == Code.Call || instruction.OpCode.Code == Code.Callvirt)
				{
					MemberReference member = instruction.Operand as MemberReference;
					if (member.Name.Equals("ToString"))
					{
						CheckStack(instruction.Previous, method, messageCollection);
					}
				}
			}


			return messageCollection.Count == 0 ? runner.RuleSuccess : messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition method, Runner runner)
		{			
			MessageCollection messageCollection = new MessageCollection ();
			
			foreach (Instruction ins in method.Body.Instructions)
				if (ins.OpCode == OpCodes.Call || ins.OpCode == OpCodes.Callvirt) {
					MethodReference calledMethod = (MethodReference) ins.Operand;
					if (calledMethod.Name == "Equals" && calledMethod.ReturnType.ReturnType.FullName == "System.Boolean")
						if (ins.Previous.OpCode == OpCodes.Ldnull) {
							Location location = new Location (method.DeclaringType.FullName, method.Name, 0);
							Message message = new Message ("You should not call Equals (null), i.e., argument should not be null", location, MessageType.Error);
							messageCollection.Add (message);
						}
				}
		
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition method, Runner runner)
		{
			string [] access_spec  = method.Attributes.ToString ().Split(',');
			MessageCollection messageCollection = new MessageCollection ();
			
			if(!IsPropertyEventOrOperator(method))
			{
				// Compiler generates an error for any other non alpha-numerics than underscore ('_'), so we just need to check the presence of underscore in method names
				if (access_spec[0] != "Private" && method.Name.IndexOf("_") != -1)
				{
					Location location = new Location (method.DeclaringType.ToString(), method.Name, 0);
					Message message = new Message ("Method name contains underscore", location, MessageType.Error);
					messageCollection.Add (message);
				}
			}
			
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition method, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			
			foreach (Instruction instruction in method.Body.Instructions) {					
				if (instruction.Operand != null) {
					if (instruction.Operand.ToString () == "System.Boolean System.String::Equals(System.String)") {
						Instruction prevInstr = instruction.Previous;
						if (prevInstr.OpCode.Name == "ldstr" && prevInstr.Operand.ToString().Length == 0) {
							Location location = new Location (method.DeclaringType.ToString(), method.Name, instruction.Offset);
							Message message = new Message ("Method uses .Equals (\"\") method to check for empty string instead of using Length property ", location, MessageType.Error);
							messageCollection.Add (message);
						}
					}
				}
			}
			
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition methodDefinition, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			if (methodDefinition.HasBody) {
				ExceptionHandlerCollection exceptionHandlerCollection = methodDefinition.Body.ExceptionHandlers;
				foreach (ExceptionHandler exceptionHandler in exceptionHandlerCollection) {
					if (exceptionHandler.Type == ExceptionHandlerType.Catch) {
						string catchTypeName = exceptionHandler.CatchType.FullName;
						if (IsForbiddenTypeInCatches (catchTypeName)) {
							if (!ThrowsGeneralException (exceptionHandler)) {
								Location location = new Location (methodDefinition.Name, methodDefinition.Name, exceptionHandler.HandlerStart.Offset);
								Message message = new Message ("Do not swallow errors catching nonspecific exceptions.", location, MessageType.Error);
								messageCollection.Add (message);
							}
						}
					}
				}
			}
			
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition method, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			Instruction prevIns;
			int offset = 0;
			bool nullReturned = false;
			foreach (Instruction ins in method.Body.Instructions)
				if (method.Name == "ToString")
					if (ins.OpCode == OpCodes.Ret) {
						prevIns = ins.Previous;
						if (prevIns.OpCode != OpCodes.Ldnull) {
							string opCodeSt;
							if (prevIns.OpCode == OpCodes.Call || prevIns.OpCode == OpCodes.Callvirt)
								opCodeSt = ReturnSt (method, prevIns.Previous);
							else 
								opCodeSt = ReturnSt (method, prevIns);
							if (opCodeSt == null && prevIns.Operand.ToString () != "System.String System.Convert::ToString(System.Object)")
								nullReturned = true;
							if (MethodReturnsNull (method, opCodeSt)) {
								nullReturned = true;
								offset = ins.Offset;
							}
						}
						else {
							nullReturned = true;
							offset = ins.Offset;
						}
					}
			if (nullReturned) {
				Location location = new Location (method.DeclaringType.FullName, method.Name, offset);
				Message message = new Message ("ToString () seems to returns null in some condition", location, MessageType.Error);
				messageCollection.Add (message);
			}
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod(MethodDefinition method, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection();

			if ((method.Attributes & MethodAttributes.SpecialName) == MethodAttributes.SpecialName && method.Name.StartsWith("set_"))
			{
				bool valueAccessed = false;
				foreach (Instruction instruction in method.Body.Instructions)
				{
					if (instruction.OpCode.Code == Code.Ldarg_1)
					{
						valueAccessed = true;
					}
				}
				if (!valueAccessed)
				{
					Location location = new Location(method.DeclaringType.Name, method.Name, 0);
					Message message = new Message(MessageString, location, MessageType.Error);
					messageCollection.Add(message);
				}
			}
			
			return messageCollection.Count > 0 ? messageCollection : null;
		}
		public MessageCollection CheckType (TypeDefinition type, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			EqualsOrGetHashCode (type);
			
			if (equals == true && getHashCode == false)
			{
				Location location = new Location (type.FullName, type.Name, 0);
				Message message = new Message ("Implements Object.Equals (Object) but does not implement Object.GetHashCode ()", location, MessageType.Error);
				messageCollection.Add (message);
			}
			else if (equals == false && getHashCode == true)
			{
				Location location = new Location (type.FullName, type.Name, 0);
				Message message = new Message ("Implements Object.GetHashCode () but does not implement Object.Equals (Object)", location, MessageType.Error);
				messageCollection.Add (message);
			}
			else
				return runner.RuleSuccess;
			
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition method, Runner runner)
		{
			MessageCollection messageCollection = new MessageCollection ();
			foreach (ParameterDefinition parameter in GetUnusedParameters (method)) {
				Location location = new Location (method.DeclaringType.Name, method.Name, 0);
				Message message = new Message (String.Format ("The parameter {0} is never used.", parameter.Name),location, MessageType.Error);
				messageCollection.Add (message);
			}
			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckMethod (MethodDefinition method, Runner runner) 
		{
			messageCollection = new MessageCollection ();
			
			CheckForUnsafeQueries (method);

			if (messageCollection.Count == 0)
				return null;
			return messageCollection;
		}
		public MessageCollection CheckType (TypeDefinition type, Runner runner) 
		{
			messageCollection = new MessageCollection ();
			
			CheckForClassFields (type);
			CheckForCommonPrefixesInFields (type);

			if (messageCollection.Count != 0)
				return messageCollection;
			return null;
		}
		private void CheckUnusedParameters (TypeDefinition type, Runner runner) 
		{
			IMethodRule avoidUnusedParameters = new AvoidUnusedParametersRule ();
			CheckMethods (avoidUnusedParameters, type.Methods, runner);
			CheckMethods (avoidUnusedParameters, type.Constructors, runner);
		}
		public MessageCollection CheckType (TypeDefinition type, Runner runner) 
		{
			messageCollection = new MessageCollection ();
			
			CheckAbstractClassWithoutResponsability (type);
			CheckUnnecesaryDelegation (type);
			if (!ContainsAvoidUnusedParametersRule (runner))
				CheckUnusedParameters (type, runner);

			if (messageCollection.Count != 0)
				return messageCollection;
			return null;
		}
		private void CheckMethods (IMethodRule rule, ICollection methods, Runner runner) 
		{
			foreach (MethodDefinition method in methods) {
				AddExistingMessages (rule.CheckMethod (method, runner));
			}
		}