/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
		{
			return new EnumConversionRule(EnumType)
			       	{
			       		IgnoreCase = IgnoreCase
			       	};
		}
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            return new LengthStringRule(Minimum, Maximum)
                   	{
                   		TrimWhiteSpace = TrimWhiteSpace
                   	};
        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            return new RegexRule(validationExpression)
                   	{
						RegexOptions = RegexOptions
                   	};
        }
        /// <remarks>
        /// null is an invalid value for both <paramref name="rule"/> and <paramref name="errorMessage"/>. 
        /// Due to performance concerns <see cref="ArgumentNullException"/> will no be thrown.
        /// So just don't pass in null or an empty string.
        /// </remarks>
        /// <param name="rule">The <see cref="Rule"/> that this <see cref="ValidationError"/> has been generated from.</param>
        /// <param name="errorMessage">The error message.</param>
		/// <param name="attemptedValue">The invalid member's value</param>
        /// <param name="infoDescriptor">The <see cref="InfoDescriptor"/> that this <see cref="ValidationError"/> has been generated from.</param>
        public ValidationError(Rule rule, string errorMessage, object attemptedValue, InfoDescriptor infoDescriptor)
        {
            //Dont guard these. the performance hit is not worth the minor help it gives developers. 
            Rule = rule;
            ErrorMessage = errorMessage;
			AttemptedValue = attemptedValue;
            InfoDescriptor = infoDescriptor;
        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
			return new RangeRule<long>(Minimum, Maximum)
			{
				EqualsMaximumIsValid = EqualsMaximumIsValid,
				EqualsMinimumIsValid = EqualsMinimumIsValid
			};
        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            var equalityComparer = (IEqualityComparer) TypeExtensions.GetStaticProperty(EqualityComparerTypeName, EqualityComparerPropertyName);
            return new EnumerableDuplicateRule()
                   	{
						Comparer = equalityComparer
                   	};
        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
			var equalityComparer = (IEqualityComparer)TypeExtensions.GetStaticProperty(EqualityComparerTypeName, EqualityComparerPropertyName);

			return new LengthCollectionRule(Minimum, Maximum)
			       	{
			       		ExcludeDuplicatesFromCount = ExcludeDuplicatesFromCount,
						Comparer = equalityComparer
			       	};
		}
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            var minimumDateTime = DateTimeConverter.Parse(Minimum);
            var maximumDateTime = DateTimeConverter.Parse(Maximum);
			return new RangeRule<DateTime>(minimumDateTime, maximumDateTime)
			{
				EqualsMaximumIsValid = EqualsMaximumIsValid,
				EqualsMinimumIsValid = EqualsMinimumIsValid
			};
        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            if (initialValue == null)
            {
                return RequiredObjectRuleCreator.ReadConfig(ErrorMessage, UseErrorMessageProvider, null, infoDescriptor.RuntimeType);
            }
            else
            {
                return RequiredObjectRuleCreator.ReadConfig(ErrorMessage, UseErrorMessageProvider, XmlReader.Create(new StringReader(initialValue)), infoDescriptor.RuntimeType);
            }
        }
		/// <inheritdoc />
        public override bool Validate(object targetMemberValue, object context, InfoDescriptor infoDescriptor)
        {
            if (targetMemberValue != null)
            {
                var valueAsString = (string) targetMemberValue;
                if (TrimWhiteSpace)
                {
                    valueAsString = valueAsString.Trim();
                }
                return LengthValidationHelper.IsLengthValid(valueAsString.Length, Minimum, Maximum);
            }
            return true;
        }
		/// <inheritdoc />
        public override bool Validate(object targetMemberValue, object context, InfoDescriptor infoDescriptor)
        {
            bool isValid;
            if (targetMemberValue == null)
            {
                return true;
            }
            else
            {
                return TypeExtensions.IsEnumDefined(EnumType, infoDescriptor.RuntimeType, targetMemberValue, IgnoreCase);
            }

        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            if (initialValue.HasValue)
            {
                return new RequiredRule<long>
                       	{
							InitialValue = initialValue.Value
                       	};
            }
            else
            {
                return new RequiredRule<long>();
            }
        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            var initialValueDateTime = DateTimeConverter.ParseNullable(InitialValue);
            if (initialValueDateTime.HasValue)
            {
                return new RequiredRule<DateTime>
                       	{
							InitialValue = initialValueDateTime.Value
                       	};
            }
            else
            {
                return new RequiredRule<DateTime>();
            }
        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            var initialValueDecimal = (decimal?) initialValue;
            if (initialValue.HasValue)
            {
                return new RequiredRule<decimal>
                       	{
InitialValue = initialValueDecimal.Value
                       	};
            }
            else
            {
                return new RequiredRule<decimal>();
            }
        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
		{
			var instance = new ValidatableRule();
			if (UseMemberErrorMessages)
			{
				if (ErrorMessage == null)
				{
					instance.UseMemberErrorMessages = true;
				}
				else
				{
					throw new InvalidOperationException("Cannot use 'useMemberErrorMessages'");
				}
			}
			return instance;
		}
		/// <inheritdoc />
        public override ValidationError BaseValidate(object targetObjectValue, object targetMemberValue, object context, InfoDescriptor infoDescriptor)
		{
		    if (targetMemberValue != null)
		    {
		        var validatable = targetMemberValue as IValidatable;
		        bool isValid;
		        string errorMessages = null;
		        if (validatable == null)
		        {
		            var validationErrors = PropertyValidationManager.ValidateAll(targetMemberValue, RuleSet, context);
		            isValid = validationErrors.Count == 0;
                    if (!isValid)
                    {
                        errorMessages = ResultFormatter.GetConcatenatedErrorMessages(validationErrors);
                    }
		        }
		        else
		        {
		            isValid = validatable.IsValid;
		            var messages = validatable.ErrorMessages;
                    if (!isValid)
                    {
                        errorMessages = ResultFormatter.GetConcatenatedErrorMessages(messages);
                    }
		        }
		        if (!isValid)
		        {
		            if (UseErrorMessageProvider)
		            {
		                var errorMessage = ConfigurationService.ErrorMessageProvider.RetrieveErrorMessage(this, targetObjectValue, targetMemberValue, context);
                        return new ValidationError(this, errorMessage, infoDescriptor, targetMemberValue);
		            }
		            else if (UseMemberErrorMessages)
		            {
                        return new ValidationError(this, errorMessages, infoDescriptor, targetMemberValue);
		            }
		            else
		            {
		                return CreateValidationError(targetObjectValue, targetMemberValue, context, infoDescriptor);
		            }
		        }
		    }
		    return null;
		}
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
		{
		    Guard.ArgumentNotNull(infoDescriptor, "infoDescriptor");
		    if (InitialValueAsString == null)
		    {
		        if (InitialValueAsLong == null)
		        {
		            return RequiredEnumRuleCreator.ReadConfig(ErrorMessage, UseErrorMessageProvider, infoDescriptor.RuntimeType);
		        }
		        else
		        {
		            return RequiredEnumRuleCreator.ReadConfig(InitialValueAsLong.Value, ErrorMessage, UseErrorMessageProvider, infoDescriptor.RuntimeType);
		        }
		    }
		    else
		    {
		        return RequiredEnumRuleCreator.ReadConfig(InitialValueAsString, ErrorMessage, UseErrorMessageProvider, infoDescriptor.RuntimeType);
		    }
		}
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            if (InitialValue == null)
            {
                return new RequiredStringRule
                       	{
                       		TrimWhiteSpace = TrimWhiteSpace
                       	};
            }
            else
            {
                return new RequiredStringRule
                       	{
                       		InitialValue = InitialValue,
							TrimWhiteSpace = TrimWhiteSpace,
							IgnoreCase = IgnoreCase
                       	};
            }
        }
        /// <inheritdoc />
        public override bool Validate(object targetMemberValue, object context, InfoDescriptor infoDescriptor)
        {
            if (targetMemberValue == null)
            {
                return true;
            }
            else
            {
                var s = (string) targetMemberValue;
                if (s.Length == 0)
                {
                    return true;
                }
                else
                {
                    var m = Regex.Match(s, ValidationExpression, RegexOptions);
                    return (m.Success && (m.Index == 0) && (m.Length == s.Length));
                }
            }

        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            Guid? initialValueGuid;
            if (string.IsNullOrEmpty(InitialValue))
            {
                initialValueGuid = null;
            }
            else
            {
                initialValueGuid = new Guid(InitialValue);
            }
            if (initialValueGuid.HasValue)
            {
                return new RequiredRule<Guid>
                       	{
							InitialValue = initialValueGuid.Value
                       	};
            }
            else
            {
                return new RequiredRule<Guid>();
            }
        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
		{
			var numberFormatInfo = (NumberFormatInfo) TypeExtensions.GetStaticProperty(NumberFormatInfoTypeName, NumberFormatInfoPropertyName);
			//TODO: populate other properties
			return new NumberConversionRule(TypeCode)
			       	{
			       		NumberFormatInfo = numberFormatInfo
			       	};
		}
		/// <inheritdoc />
        public override bool Validate(object targetMemberValue, object context, InfoDescriptor infoDescriptor)
        {
            if (targetMemberValue != null)
            {
                int count;
                if (ExcludeDuplicatesFromCount)
                {
                    count = GetCountExcludeDuplicates(targetMemberValue);
                }
                else
                {
                    count = GetCount(targetMemberValue);
                }
                return LengthValidationHelper.IsLengthValid(count, Minimum, Maximum);
            }

            return true;
        }
		/// <inheritdoc />
		internal override void CheckType(InfoDescriptor infoDescriptor)
        {
		    //var targetMemberRuntimeTypeHandle = infoDescriptor.RuntimeType;
            //var typeToCheck = Type.GetTypeFromHandle(targetMemberRuntimeTypeHandle);
            var typeToCheck = infoDescriptor.RuntimeType;
            var isGenericICollection = genericCollectionType.IsAssignableFrom(typeToCheck, true);
            var isICollection = collectionType.IsAssignableFrom(typeToCheck, true);
            
            if (!isICollection && !isGenericICollection)
            {
                throw new ArgumentException("Property must be a ICollection<T> or ICollection to be used for the LengthCollectionRule.");
            }
        }
 	/// <inheritdoc/>
 	public override Rule CreateInstance(InfoDescriptor infoDescriptor)
     {
         return new CustomRule(ValidationType, ValidationMethod, RuleInterpretation);
     }
 private static void AddRuleToInfoDescriptor(IList<RuleData> list, InfoDescriptor infoDescriptor)
 {
     for (var ruleDateIndex = 0; ruleDateIndex < list.Count; ruleDateIndex++)
     {
         var ruleData = list[ruleDateIndex];
         var runtimeType = infoDescriptor.RuntimeType;
         var rule = GetRule(ruleData, runtimeType);
         infoDescriptor.Rules.Add(rule);
     }
 }
 /// <inheritdoc/>
 public sealed override bool Validate(object targetObjectValue, object targetMemberValue, object context, InfoDescriptor infoDescriptor)
 {
     return Validate(targetMemberValue, context, infoDescriptor);
 }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            return new CompareRule<long>(ValueToCompare, Operator);
        }
 /// <summary>
 /// Validate the member this <see cref="Rule"/> is applied to.
 /// </summary>
 /// <returns><see langword="true"/> if the member is valid; otherwise <see langword="false"/>.</returns>
 /// <param name="targetMemberValue">The value of the member to validate.</param>
 /// <param name="context">An <see cref="object"/> that contains data for the <see cref="Rule"/> to validate. The default is null.</param>
 /// <param name="infoDescriptor">The <see cref="InfoDescriptor"/> for the member being validated.</param>
 public abstract bool Validate(object targetMemberValue, object context, InfoDescriptor infoDescriptor);
		/// <inheritdoc />
        public override bool Validate(object targetMemberValue, object context, InfoDescriptor infoDescriptor)
        {
            if (targetMemberValue == null)
            {
                return true;
            }
            else
            {	
                var memberValueAsString = (string) targetMemberValue;
				if (RemoveWhiteSpace)
				{
					var stringBuilder = new StringBuilder(memberValueAsString.Length);
					foreach (var c in memberValueAsString)
					{
						if (!char.IsWhiteSpace(c))
						{
							stringBuilder.Append(c);
						}
					}
					memberValueAsString = stringBuilder.ToString();
				}
            	if (memberValueAsString.Length == 0)
                {
                    return true;
                }
                else
                {
                	return GetIsValid(memberValueAsString);
                }
            }
        }
		/// <inheritdoc/>
		public override Rule CreateInstance(InfoDescriptor infoDescriptor)
        {
            return new ComparePropertyRule(PropertyToCompare, Operator);
        }