 	</cfscript>
 </cffunction>
 
-<cffunction name="onMissingMethod" returntype="any" access="public" output="false">
+<cffunction name="propertyNames" returntype="string" access="public" output="false"
+	hint="Returns a list of property names (ordered by their respective column's ordinal position in the database table)."
+	examples=
+	'
+		<!--- Get a list of the property names in use in the user model --->
+  		<cfset propNames = model("user").propertyNames()>
+	'
+	categories="model-class" chapters="object-relational-mapping" functions="columnNames,dataSource,property,table,tableName">
+	<cfreturn variables.wheels.class.propertyList>
+</cffunction>
+
+<cffunction name="table" returntype="void" access="public" output="false"
+	hint="Use this method to tell Wheels what database table to connect to for this model. You only need to use this method when your table naming does not follow the standard Wheels convention of a singular object name mapping to a plural table name."
+	examples=
+	'
+		<!--- In models/User.cfc --->
+		<cffunction name="init">
+			<!--- Tell Wheels to use the `tbl_USERS` table in the database for the `user` model instead of the default (which would be `users`) --->
+			<cfset table("tbl_USERS")>
+		</cffunction>
+	'
+	categories="model-initialization" chapters="object-relational-mapping" functions="columnNames,dataSource,property,propertyNames,tableName">
+	<cfargument name="name" type="string" required="true" hint="Name of the table to map this model to.">
+	<cfscript>
+		variables.wheels.class.tableName = arguments.name;
+	</cfscript>
+</cffunction>
+
+<cffunction name="tableName" returntype="string" access="public" output="false"
+	hint="Returns the name of the database table that this model is mapped to."
+	examples=
+	'
+		<!--- Check what table the user model uses --->
+		<cfset whatAmIMappedTo = model("user").tableName()>
+	'
+	categories="model-class" chapters="object-relational-mapping" functions="columnNames,dataSource,property,propertyNames,table">
+	<cfreturn variables.wheels.class.tableName>
+</cffunction>
+
+<cffunction name="onMissingMethod" returntype="any" access="public" output="false" hint="This method handles dynamic finders, property and association methods. It is not part of the public API.">
 	<cfargument name="missingMethodName" type="string" required="true">
 	<cfargument name="missingMethodArguments" type="struct" required="true">
 	<cfscript>

		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))
