 			{
 				if ($callback("beforeValidationOnCreate", arguments.callbacks) && $validate("onSave,onCreate") && $callback("afterValidation", arguments.callbacks) && $callback("afterValidationOnCreate", arguments.callbacks))
 				{
-					loc.rv = true;
+					local.rv = true;
 				}
 			}
 			else
 			{
 				if ($callback("beforeValidationOnUpdate", arguments.callbacks) && $validate("onSave,onUpdate") && $callback("afterValidation", arguments.callbacks) && $callback("afterValidationOnUpdate", arguments.callbacks))
 				{
-					loc.rv = true;
+					local.rv = true;
 				}
 			}
 		}
 		$validateAssociations(callbacks=arguments.callbacks);
-	</cfscript>
-	<cfreturn loc.rv>
-</cffunction>
-
-<!--- PRIVATE METHODS --->
-
-<cffunction name="$registerValidation" returntype="void" access="public" output="false" hint="Called from the high level validation helpers to register the validation in the class struct of the model.">
-	<cfargument name="when" type="string" required="true">
-	<cfscript>
-		var loc = {};
+		return local.rv;
+	}
+
+	/*
+	* PRIVATE METHODS
+	*/
+
+	/**
+    * Called from the high level validation helpers to register the validation in the class struct of the model.
+    */
+	public void function $registerValidation(required string when) {
 
 		// combine method / methods and property / properties into one variables for easier processing below
 		// validate, validateOnCreate and validateOnUpdate do not take the properties argument however other validations do

			arguments.maximum = arguments.within[2];
		}

		if ((arguments.maximum && loc.lenValue > arguments.maximum) || (arguments.minimum && loc.lenValue < arguments.minimum) || (arguments.exactly && loc.lenValue != arguments.exactly))
		{
			addError(property=arguments.property, message=$validationErrorMessage(argumentCollection=arguments));
		}
	</cfscript>
</cffunction>

<cffunction name="$validatesNumericalityOf" returntype="void" access="public" output="false" hint="Adds an error if the object property fail to pass the validation setup in the @validatesNumericalityOf method.">
	<cfscript>
		if (!IsNumeric(this[arguments.property]) || (arguments.onlyInteger && Round(this[arguments.property]) != this[arguments.property]) || (IsNumeric(arguments.greaterThan) && this[arguments.property] <= arguments.greaterThan) || (IsNumeric(arguments.greaterThanOrEqualTo) && this[arguments.property] < arguments.greaterThanOrEqualTo) || (IsNumeric(arguments.equalTo) && this[arguments.property] != arguments.equalTo) || (IsNumeric(arguments.lessThan) && this[arguments.property] >= arguments.lessThan) || (IsNumeric(arguments.lessThanOrEqualTo) && this[arguments.property] > arguments.lessThanOrEqualTo) || (IsBoolean(arguments.odd) && arguments.odd && !BitAnd(this[arguments.property], 1)) || (IsBoolean(arguments.even) && arguments.even && BitAnd(this[arguments.property], 1)))
		{
			addError(property=arguments.property, message=$validationErrorMessage(argumentCollection=arguments));
		}
	</cfscript>
</cffunction>

<cffunction name="$validatesUniquenessOf" returntype="void" access="public" output="false" hint="Adds an error if the object property fail to pass the validation setup in the @validatesUniquenessOf method.">
	<cfargument name="property" type="string" required="true">
	<cfargument name="message" type="string" required="true">
	<cfargument name="scope" type="string" required="false" default="">
	<cfargument name="properties" type="struct" required="false" default="#this.properties()#">
	<cfargument name="includeSoftDeletes" type="boolean" required="false" default="true">
	<cfscript>
		var loc = {};
		if (!IsBoolean(variables.wheels.class.tableName) || variables.wheels.class.tableName)
		{
			loc.where = [];

			// create the WHERE clause to be used in the query that checks if an identical value already exists
			// wrap value in single quotes unless it's numeric
			// example: "userName='Joe'"
			loc.part = arguments.property & "=" & variables.wheels.class.adapter.$quoteValue(str=this[arguments.property], type=validationTypeForProperty(arguments.property));
			if (Right(loc.part, 3) == "=''" && ListFindNoCase("integer,float,boolean", validationTypeForProperty(arguments.property)))
			{
				// when numeric property but blank we need to translate to IS NULL
				loc.part = SpanExcluding(loc.part, "=") & " IS NULL";
			}
			ArrayAppend(loc.where, loc.part);

			// add scopes to the WHERE clause if passed in, this means that checks for other properties are done in the WHERE clause as well
			// example: "userName='Joe'" becomes "userName='Joe' AND account=1" if scope is "account" for example
			arguments.scope = $listClean(arguments.scope);
			loc.iEnd = ListLen(arguments.scope);
			for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
			{
				loc.item = ListGetAt(arguments.scope, loc.i);
				loc.part = loc.item & "=" & variables.wheels.class.adapter.$quoteValue(str=this[loc.item], type=validationTypeForProperty(loc.item));
				if (Right(loc.part, 3) == "=''" && ListFindNoCase("integer,float,boolean", validationTypeForProperty(loc.item)))
				{
					// when numeric property but blank we need to translate to IS NULL
					loc.part = SpanExcluding(loc.part, "=") & " IS NULL";
				}
				ArrayAppend(loc.where, loc.part);
			}

			// try to fetch existing object from the database
			loc.existingObject = findOne(select=primaryKey(), where=ArrayToList(loc.where, " AND "), reload=true, includeSoftDeletes=arguments.includeSoftDeletes, callbacks=false);

			// we add an error if an object was found in the database and the current object is either not saved yet or not the same as the one in the database
			if (IsObject(loc.existingObject) && (isNew() || loc.existingObject.key() != key($persisted=true)))
			{
				addError(property=arguments.property, message=$validationErrorMessage(argumentCollection=arguments));
			}
		}
	</cfscript>
</cffunction>

<cffunction name="$validationExists" returntype="boolean" access="public" output="false">
	<cfargument name="property" type="string" required="true">
	<cfargument name="validation" type="string" required="true">
	<cfscript>
		var loc = {};

		// checks to see if a validation has been created for a property
		loc.rv = false;
		for (loc.key in variables.wheels.class.validations)
		{
			if (StructKeyExists(variables.wheels.class.validations, loc.key))
			{
				loc.eventArray = variables.wheels.class.validations[loc.key];
				loc.iEnd = ArrayLen(loc.eventArray);
				for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
				{
					if (StructKeyExists(loc.eventArray[loc.i].args, "property") && loc.eventArray[loc.i].args.property == arguments.property && loc.eventArray[loc.i].method == "$#arguments.validation#")
					{
						loc.rv = true;
						break;
					}
				}
			}
		}
	</cfscript>
	<cfreturn loc.rv>
</cffunction>

<cfscript>
	/*
	* PUBLIC MODEL INITIALIZATION METHODS
	*/

	public void function automaticValidations(required boolean value) {
		variables.wheels.class.automaticValidations = arguments.value;
	}

	public void function validate(
		string methods="",
		string condition="",
		string unless="",
		string when="onSave"
	) {
		$registerValidation(argumentCollection=arguments);
	}

	public void function validateOnCreate(
		string methods="",
		string condition="",
		string unless=""
	) {
		$registerValidation(when="onCreate", argumentCollection=arguments);
	}

	public void function validateOnUpdate(
		string methods="",
		string condition="",
		string unless=""
	) {
		$registerValidation(when="onUpdate", argumentCollection=arguments);
	}

	public void function validatesConfirmationOf(
		string properties="",
		string message,
		string when="onSave",
		string condition="",
		string unless=""
	) {
		$args(name="validatesConfirmationOf", args=arguments);
		$registerValidation(methods="$validatesConfirmationOf", argumentCollection=arguments);
	}

	public void function validatesExclusionOf(
		string properties="",
		required string list,
		string message,
		string when="onSave",
		boolean allowBlank,
		string condition="",
		string unless=""
	) {
		$args(name="validatesExclusionOf", args=arguments);
		arguments.list = $listClean(arguments.list);
		$registerValidation(methods="$validatesExclusionOf", argumentCollection=arguments);
	}

	public void function validatesFormatOf(
		string properties="",
		string regEx="",
		string type="",
		string message,
		string when="onSave",
		boolean allowBlank,
		string condition="",
		string unless=""
	) {
		$args(name="validatesFormatOf", args=arguments);
		if (application.wheels.showErrorInformation)
		{
