			function validate(objArguments, objTypes)
			{
				if((objArguments != null) 
					&& (objTypes != null) 
					&& (objArguments.length != null)
					&& (objTypes != null) 
					&& (objArguments.length > 0) 
					&& (objTypes.length > 0)
					&& (objArguments.length == objTypes.length))
				{
					var intNumberOfArguments = objArguments.length;
					for(var i = 0; i < intNumberOfArguments; ++i)
					{
						if((typeof(objArguments[i]) != objTypes[i].toLowerCase()) 
							|| (objArguments[i] == null))
						{
							return false;
						}
					}
					return true;
				}
				return false;
			};
		
			function sortRectangularArray(objRectangularArray, intStartRowIndex, intFinishRowIndex, intSortColumnIndex, boolSortColumnIsCaseInsensitiveString, boolSortInAscendingOrder)
			{
				if(validate(arguments, new Array("object", "number", "number", "number", "boolean", "boolean")))
				{
					if(objRectangularArray.length != null)
					{
						var intNumberOfRows = objRectangularArray.length;
						if((intNumberOfRows > 0) 
							&& (intStartRowIndex >= 0) 
							&& (intStartRowIndex <= intNumberOfRows) 
							&& (intFinishRowIndex >= 0) 
							&& (intFinishRowIndex <= intNumberOfRows)
							&& (intStartRowIndex < intFinishRowIndex))
						{
							if(objRectangularArray[0].length != null)
							{
								var intNumberOfColumns = objRectangularArray[0].length;
								if((intNumberOfColumns > 0)
									&& (intSortColumnIndex >= 0) 
									&& (intSortColumnIndex <= intNumberOfColumns))
								{
									var objTemporary = new Array(intNumberOfColumns);
									if((intFinishRowIndex - intStartRowIndex) == 1)
									{
										if((objRectangularArray[intStartRowIndex][intSortColumnIndex]) > (objRectangularArray[intFinishRowIndex][intSortColumnIndex]))
										{
											swapRows(objRectangularArray, intFinishRowIndex, intStartRowIndex);
										}
									}
									for(var i = 0; i < intNumberOfColumns; ++i)
									{
										objTemporary[i] = objRectangularArray[parseInt(((intStartRowIndex + intFinishRowIndex) / 2), 10)][i];
										objRectangularArray[parseInt(((intStartRowIndex + intFinishRowIndex) / 2), 10)][i] = objRectangularArray[intStartRowIndex][i];
										objRectangularArray[intStartRowIndex][i] = objTemporary[i];
									}
									var intLowerBoundary = (intStartRowIndex + 1);
									var intUpperBoundary = intFinishRowIndex;
									if(boolSortInAscendingOrder)
									{
										do
										{
											if(boolSortColumnIsCaseInsensitiveString)
											{
												while((intLowerBoundary < intUpperBoundary) 
													&& (objRectangularArray[intLowerBoundary][intSortColumnIndex].toLowerCase() <= objTemporary[intSortColumnIndex].toLowerCase()))
												{
													++intLowerBoundary;
												}
												while(objRectangularArray[intUpperBoundary][intSortColumnIndex].toLowerCase() > objTemporary[intSortColumnIndex].toLowerCase())
												{
													--intUpperBoundary;
												}
											}
											else
											{
												while((intLowerBoundary < intUpperBoundary) 
													&& (objRectangularArray[intLowerBoundary][intSortColumnIndex] <= objTemporary[intSortColumnIndex]))
												{
													++intLowerBoundary;
												}
												while(objRectangularArray[intUpperBoundary][intSortColumnIndex] > objTemporary[intSortColumnIndex])
												{
													--intUpperBoundary;
												}
											}
											if(intLowerBoundary < intUpperBoundary)
											{
												swapRows(objRectangularArray, intLowerBoundary, intUpperBoundary);
											}
										}
										while(intLowerBoundary < intUpperBoundary);
									}
									else
									{
										do
										{
											if(boolSortColumnIsCaseInsensitiveString)
											{
												while((intLowerBoundary < intUpperBoundary) 
													&& (objRectangularArray[intLowerBoundary][intSortColumnIndex].toLowerCase() >= objTemporary[intSortColumnIndex].toLowerCase()))
												{
													++intLowerBoundary;
												}
												while(objRectangularArray[intUpperBoundary][intSortColumnIndex].toLowerCase() < objTemporary[intSortColumnIndex].toLowerCase())
												{
													--intUpperBoundary;
												}
											}
											else
											{
												while((intLowerBoundary < intUpperBoundary) 
													&& (objRectangularArray[intLowerBoundary][intSortColumnIndex] >= objTemporary[intSortColumnIndex]))
												{
													++intLowerBoundary;
												}
												while(objRectangularArray[intUpperBoundary][intSortColumnIndex] < objTemporary[intSortColumnIndex])
												{
													--intUpperBoundary;
												}
											}
											if(intLowerBoundary < intUpperBoundary)
											{
												swapRows(objRectangularArray, intLowerBoundary, intUpperBoundary);
											}
										}
										while(intLowerBoundary < intUpperBoundary);
									}
									for(var j = 0; j < intNumberOfColumns; ++j)
									{
										objRectangularArray[intStartRowIndex][j] = objRectangularArray[intUpperBoundary][j];
										objRectangularArray[intUpperBoundary][j] = objTemporary[j];
									}
									if(intStartRowIndex < (intUpperBoundary - 1))
									{
										sortRectangularArray(objRectangularArray, intStartRowIndex, (intUpperBoundary - 1), intSortColumnIndex, boolSortColumnIsCaseInsensitiveString, boolSortInAscendingOrder);
									}
									if((intUpperBoundary + 1) < intFinishRowIndex)
									{
										sortRectangularArray(objRectangularArray, (intUpperBoundary + 1), intFinishRowIndex, intSortColumnIndex, boolSortColumnIsCaseInsensitiveString, boolSortInAscendingOrder);
									}
								}
							}
						}
					}
				}
			};

			function swapRows(objRectangularArray, intRowIndexA, intRowIndexB)
			{
				if(validate(arguments, new Array("object", "number", "number")))
				{
					var intNumberOfRows = objRectangularArray.length;
					if((intNumberOfRows > 0) 
						&& (intRowIndexA >= 0) 
						&& (intRowIndexA <= intNumberOfRows) 
						&& (intRowIndexB >= 0) 
						&& (intRowIndexB <= intNumberOfRows))
					{
						var intNumberOfColumns = objRectangularArray[0].length;
						if(intNumberOfColumns > 0)
						{
							for(var i = 0; i < intNumberOfColumns; ++i)
							{
								var objTemporary = objRectangularArray[intRowIndexA][i];
								objRectangularArray[intRowIndexA][i] = objRectangularArray[intRowIndexB][i];
								objRectangularArray[intRowIndexB][i] = objTemporary;
							}
						}
					}
				}
			};
		
			var constDateFormat = /^[SMTWF][a-z]+,\s[JFMASOND][a-z]+\s\d\d?,\s\d{4}$/;
			var constFloatFormat = /^(\+|\-)?\d+\.\d+$/;
			var constIntegerFormat = /^(\+|\-)?\d+$/;
	
			var constDays = new Array(
				"Sunday",
				"Monday",
				"Tuesday",
				"Wednesday",
				"Thursday",
				"Friday",
				"Saturday"
			);
	
			var constMonths = new Array(
				"January", 
				"February", 
				"March", 
				"April", 
				"May", 
				"June", 
				"July", 
				"August", 
				"September", 
				"October", 
				"November", 
				"December"
			);
			
			function replaceAll(strSource, strOld, strNew)
			{
				if(validate(arguments, new Array("string", "string", "string")))
				{
					return strSource.split(strOld).join(strNew);
				}
				return "";
			};
	
			function getDayString(intDay)
			{
				if(validate(arguments, new Array("number")))
				{
					switch(intDay)
					{
						case 0:
							return constDays[0];
						case 1:
							return constDays[1];
						case 2:
							return constDays[2];
						case 3:
							return constDays[3];
						case 4:
							return constDays[4];
						case 5:
							return constDays[5];
						case 6:
							return constDays[6];
						default:
							return "";
					}
				}
				return "";
			};
			
			function getMonthString(intMonth)
			{
				if(validate(arguments, new Array("number")))
				{
					switch(intMonth)
					{
						case 0:
							return constMonths[0];
						case 1:
							return constMonths[1];
						case 2:
							return constMonths[2];
						case 3:
							return constMonths[3];
						case 4:
							return constMonths[4];
						case 5:
							return constMonths[5];
						case 6:
							return constMonths[6];
						case 7:
							return constMonths[7];
						case 8:
							return constMonths[8];
						case 9:
							return constMonths[9];
						case 10:
							return constMonths[10];
						case 11:
							return constMonths[11];
						default:
							return "";
					}
				}
				return "";
			};
			
			function isDateString(strTest)
			{
				if(validate(arguments, new Array("string")))
				{
					return constDateFormat.test(strTest);
				}
				return false;
			};
			
			function getDateString(objDate)
			{
				if(validate(arguments, new Array("object")))
				{
					return (getDayString(objDate.getDay()) + ", " + getMonthString(objDate.getMonth()) + " " + objDate.getDate() + ", " + objDate.getFullYear());
				}
				return "";
			};
			
			function getDateObject(strValue)
			{
				if(validate(arguments, new Array("string")))
				{
					var strCommaStrippedValue = replaceAll(strValue, ",", "");
					var objValueElements = strCommaStrippedValue.split(" ");
					var strMonth = objValueElements[1];
					var intMonthIndex = 0;
					var intNumberOfMonths = constMonths.length;
					for(var i = 0; i < intNumberOfMonths; ++i)
					{
						if(constMonths[i] == strMonth)
						{
							intMonthIndex = i;
							break;
						}
					}
					return new Date(objValueElements[3], intMonthIndex, objValueElements[2]);
				}
				return new Date(0);
			};
			
			function isDateObject(objTest)
			{
				if(validate(arguments, new Array("object")))
				{
					try
					{
						objTest.toGMTString();
						return true;
					}
					catch(objException)
					{
						return false;
					}
				}
				return false;
			};
			
			function isBoolean(strTest)
			{
				if(validate(arguments, new Array("string")))
				{
					if((strTest == "true") || (strTest == "false"))
					{
						return true;
					}
					else
					{
						return false;
					}
				}
				return false;
			};
		
			function getBoolean(strValue)
			{
				if(validate(arguments, new Array("string")))
				{
					if(strValue.toLowerCase() == "true")
					{
						return true;
					}
					else
					{
						return false;
					}
				}
				return false;
			};

			function isFloat(strTest)
			{
				if(validate(arguments, new Array("string")))
				{
					return constFloatFormat.test(strTest);
				}
				return false;
			};

			function getFloat(strValue)
			{
				if(validate(arguments, new Array("string")))
				{
					return parseFloat(strValue);
				}
				return 0.0;
			};

			function isInteger(strTest)
			{
				if(validate(arguments, new Array("string")))
				{
					return constIntegerFormat.test(strTest);
				}
				return false;
			};

			function getInteger(strValue)
			{
				if(validate(arguments, new Array("string")))
				{
					return parseInt(strValue, 10);
				}
				return 0;
			};

			function loadTable(strTableId, strRectangularArrayStorageVariableName)
			{
				if(validate(arguments, new Array("string", "string")))
				{
					if(eval(strRectangularArrayStorageVariableName + " = scanTable( \"" + strTableId + "\" );") != null)
					{
						return true;
					}
					return false;
				}
				return false;
			};
			
			function scanTable(strTableId)
			{
				if(validate(arguments, new Array("string")))
				{
					var objTable = document.getElementById(strTableId);
					if(objTable != null)
					{
						if(objTable.rows != null)
						{
							var intNumberOfRows = objTable.rows.length;
							if(intNumberOfRows > 1)
							{
								var intNumberOfColumns = objTable.rows[0].cells.length;
								var objRectangularArray = new Array((intNumberOfRows - 1));
								for(var i = 1; i < intNumberOfRows; ++i)
								{
									objRectangularArray[i - 1] = new Array(intNumberOfColumns);
									for(var j = 0; j < intNumberOfColumns; ++j)
									{
										var strCellValue = objTable.rows[i].cells[j].innerHTML;
										if(isDateString(strCellValue))
										{
											objRectangularArray[i - 1][j] = getDateObject(strCellValue);
										}
										else
										{
											if(isBoolean(strCellValue))
											{
												objRectangularArray[i - 1][j] = getBoolean(strCellValue);
											}
											else if(isFloat(strCellValue))
											{
												objRectangularArray[i - 1][j] = getFloat(strCellValue);
											}
											else if(isInteger(strCellValue))
											{
												objRectangularArray[i - 1][j] = getInteger(strCellValue);
											}
											else
											{
												objRectangularArray[i - 1][j] = strCellValue;
											}
										}
									}
								}
								return objRectangularArray;
							}
							return null;
						}
						return null;
					}
					return null;
				}
				return null;
			};
			
			function sortTable(strTableId, objRectangularArray, intSortColumnIndex, boolSortColumnIsCaseInsensitiveString, boolSortInAscendingOrder)
			{
				if(validate(arguments, new Array("string", "object", "number", "boolean", "boolean")))
				{
					sortRectangularArray(objRectangularArray, 0, (objRectangularArray.length - 1), intSortColumnIndex, boolSortColumnIsCaseInsensitiveString, boolSortInAscendingOrder);
					populateTable(strTableId, objRectangularArray);
				}
			};

			function populateTable(strTableId, objRectangularArrayStorageVariable)
			{
				if(validate(arguments, new Array("string", "object")))
				{
					var objTable = document.getElementById(strTableId);
					if(objTable != null)
					{
						if(objTable.rows != null)
						{
							var intNumberOfRows = objRectangularArrayStorageVariable.length;
							if(intNumberOfRows > 1)
							{
								if(objRectangularArrayStorageVariable[0].length != null)
								{
									var intNumberOfColumns = objRectangularArrayStorageVariable[0].length;
									if(intNumberOfColumns > 0)
									{
										for(var i = 1; i <= intNumberOfRows; ++i)
										{
											for(var j = 0; j < intNumberOfColumns; ++j)
											{
												var objTemporary = objRectangularArrayStorageVariable[i - 1][j];
												if(isDateObject(objTemporary))
												{
													objTable.rows[i].cells[j].innerHTML = getDateString(objTemporary);
												}
												else
												{
													objTable.rows[i].cells[j].innerHTML = objTemporary.toString();
												}
											}
										}
									}
								}
							}
						}
					}
				}
			};