 	<cfreturn loc.returnValue>
 </cffunction>
 
-<cffunction name="columnNames" returntype="string" access="public" output="false" hint="Returns a list of column names (ordered by their position in the database table).">
-	<cfreturn variables.wheels.class.columnList>
-</cffunction>
-
-<cffunction name="propertyNames" returntype="string" access="public" output="false" hint="Returns a list of property names (ordered by their respective column's position in the database table).">
-	<cfreturn variables.wheels.class.propertyList>
-</cffunction>
-
-<cffunction name="dataSource" returntype="void" access="public" output="false" hint="Use this method to override the data source connection information for a particular model.">
-	<cfargument name="datasource" type="string" required="true" hint="the data source name to connect to">
-	<cfargument name="username" type="string" required="false" default="" hint="the username for the data source">
-	<cfargument name="password" type="string" required="false" default="" hint="the password for the data source">
-	<cfscript>
-		StructAppend(variables.wheels.class.connection, arguments, true);
+<cffunction name="$propertyValue" returntype="string" access="public" output="false">
+	<cfargument name="name" type="string" required="true">
+	<cfscript>
+		var loc = {};
+		loc.returnValue = "";
+		loc.iEnd = ListLen(arguments.name);
+		for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
+		{
+			loc.returnValue = ListAppend(loc.returnValue, this[ListGetAt(arguments.name, loc.i)]);
+		}
+	</cfscript>
+	<cfreturn loc.returnValue>
+</cffunction>
+
+<cffunction name="$setDefaultValues" returntype="any" access="public" output="false">
+	<cfscript>
+		var loc = {};
+		loc.iEnd = ListLen(variables.wheels.class.propertyList);
+		for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
+		{
+			loc.iItem = ListGetAt(variables.wheels.class.propertyList, loc.i);
+			if (Len(variables.wheels.class.properties[loc.iItem].defaultValue) && (!StructKeyExists(this, loc.iItem) || !Len(this[loc.iItem])))
+			{
+				// set the default value unless it is blank or a value already exists for that property on the object
+				this[loc.iItem] = variables.wheels.class.properties[loc.iItem].defaultValue;
+			}
+		}
+	</cfscript>
+</cffunction>
+
+<cffunction name="$setForeignKeyValues" returntype="void" access="public" output="false">
+	<cfargument name="missingMethodArguments" type="struct" required="true">
+	<cfargument name="keys" type="string" required="true">
+	<cfargument name="setToNull" type="boolean" required="false" default="false">
+	<cfscript>
+		var loc = {};
+		loc.iEnd = ListLen(arguments.keys);
+		for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
+		{
+			if (arguments.setToNull)
+				arguments.missingMethodArguments[ListGetAt(arguments.keys, loc.i)] = "";
+			else
+				arguments.missingMethodArguments[ListGetAt(arguments.keys, loc.i)] = this[ListGetAt(variables.wheels.class.keys, loc.i)];
+		}
 	</cfscript>
 </cffunction>
 

		else
			arguments.missingMethodArguments.key = loc.keyOrObject;
	</cfscript>
</cffunction>

<cffunction name="$propertyValue" returntype="string" access="public" output="false">
	<cfargument name="name" type="string" required="true">
	<cfscript>
		var loc = {};
		loc.returnValue = "";
		loc.iEnd = ListLen(arguments.name);
		for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
		{
			loc.returnValue = ListAppend(loc.returnValue, this[ListGetAt(arguments.name, loc.i)]);
		}
	</cfscript>
	<cfreturn loc.returnValue>
</cffunction>

<cffunction name="$setForeignKeyValues" returntype="void" access="public" output="false">
	<cfargument name="missingMethodArguments" type="struct" required="true">
	<cfargument name="keys" type="string" required="true">
	<cfargument name="setToNull" type="boolean" required="false" default="false">
	<cfscript>
		var loc = {};
		loc.iEnd = ListLen(arguments.keys);
		for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
		{
			if (arguments.setToNull)
				arguments.missingMethodArguments[ListGetAt(arguments.keys, loc.i)] = "";
			else
				arguments.missingMethodArguments[ListGetAt(arguments.keys, loc.i)] = this[ListGetAt(variables.wheels.class.keys, loc.i)];
		}
	</cfscript>
</cffunction>

<cffunction name="properties" returntype="any" access="public" output="false">
	<cfargument name="values" type="any" required="false" default="">
	<cfscript>
	var loc = {};

	// when a structure is passed in, set the properties of the object to values within the structure
	if(isStruct(arguments.values))
	{
		for(loc.key in arguments.values)
		{
			if(ListFindNoCase(variables.wheels.class.propertyList, loc.key))
			{
				this[loc.key] = arguments.values[loc.key];
			}
		}
		return;
	}

	// by default we will return a structure containing the properties and their current values
	loc.returnvalue = {};
	loc.properties = ListToArray(variables.wheels.class.propertyList);
	loc.iEnd = ArrayLen(loc.properties);
	for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
	{
		loc.property = loc.properties[loc.i];
		loc.returnvalue[loc.property] = "";
		if(structkeyexists(this, loc.property))
		{
			loc.returnvalue[loc.property] = this[loc.property];
		}
		else
		{
			loc.returnvalue[loc.property] = variables.wheels.class.properties[loc.property].defaultValue;
		}
	}
	return loc.returnvalue;
	</cfscript>
</cffunction>
<cffunction name="columnNames" returntype="string" access="public" output="false"
	hint="Returns a list of column names in the table mapped to this model. The list is ordered according to the columns ordinal position in the database table."
	examples=
	'
		<!--- Get a list of all the column names in the table mapped to the author model --->
		<cfset columns = model("author").columnNames()>
	'
	categories="model-class" chapters="object-relational-mapping" functions="dataSource,property,propertyNames,table,tableName">
	<cfreturn variables.wheels.class.columnList>
</cffunction>

<cffunction name="dataSource" returntype="void" access="public" output="false"
	hint="Use this method to override the data source connection information for this model."
	examples=
	'
		<!--- In models/User.cfc --->
		<cffunction name="init">
			<!--- Tell Wheels to use the data source named `users_source` instead of the default one whenever this model makes SQL calls  --->
  			<cfset dataSource("users_source")>
		</cffunction>
	'
	categories="model-initialization" chapters="object-relational-mapping" functions="columnNames,property,propertyNames,table,tableName">
	<cfargument name="datasource" type="string" required="true" hint="The data source name to connect to.">
	<cfargument name="username" type="string" required="false" default="" hint="The username for the data source.">
	<cfargument name="password" type="string" required="false" default="" hint="The password for the data source.">
	<cfscript>
		StructAppend(variables.wheels.class.connection, arguments, true);
	</cfscript>
</cffunction>

<cffunction name="properties" returntype="any" access="public" output="false">
	<cfargument name="values" type="any" required="false" default="">
	<cfscript>
	var loc = {};

	// when a structure is passed in, set the properties of the object to values within the structure
	if(isStruct(arguments.values))
	{
		for(loc.key in arguments.values)
		{
			if(ListFindNoCase(variables.wheels.class.propertyList, loc.key))
			{
				this[loc.key] = arguments.values[loc.key];
			}
		}
		return;
	}

	// by default we will return a structure containing the properties and their current values
	loc.returnvalue = {};
	loc.properties = ListToArray(variables.wheels.class.propertyList);
	loc.iEnd = ArrayLen(loc.properties);
	for (loc.i=1; loc.i <= loc.iEnd; loc.i++)
	{
		loc.property = loc.properties[loc.i];
		loc.returnvalue[loc.property] = "";
		if(structkeyexists(this, loc.property))
		{
			loc.returnvalue[loc.property] = this[loc.property];
		}
		else
		{
			loc.returnvalue[loc.property] = variables.wheels.class.properties[loc.property].defaultValue;
		}
	}
	return loc.returnvalue;
	</cfscript>
</cffunction>

<cffunction name="property" returntype="void" access="public" output="false"
	hint="Use this method to map an object property to either a table column with a different name than the property or to a specific SQL function. You only need to use this method when you want to override the default mapping that Wheels performs."
	examples=
	'
		<!--- In models/User.cfc --->
		<cffunction name="init">
			<!--- Tell Wheels that when we are referring to `firstName` in the CFML code it should translate to the `STR_USERS_FNAME` column when interacting with the database instead of the default (which would be the `firstname` column) --->
  			<cfset property(name="firstName", column="STR_USERS_FNAME")>
		</cffunction>
	'
	categories="model-initialization" chapters="object-relational-mapping" functions="columnNames,dataSource,propertyNames,table,tableName">
	<cfargument name="name" type="string" required="true" hint="The name that you want to use for the column or SQL function result in the CFML code.">
	<cfargument name="column" type="string" required="false" default="" hint="The name of the column in the database table to map the property to.">
	<cfargument name="sql" type="string" required="false" default="" hint="An SQL function to use to calculate the property value.">
	<cfscript>
		variables.wheels.class.mapping[arguments.name] = {};
		if (Len(arguments.column))
