	var domQuirk1IDs = new Array();
	var domQuirk1Values = new Array();
	var domQuirk1Checked = new Array();

	var tblScrollables = new Array();
	var tblMakeScrollablePositioningStarted = false;

	function domQuirkValues(doSave)
	{
		if(doSave)
		{
			domQuirk1IDs = new Array();
			domQuirk1Values = new Array();
			domQuirk1Checked = new Array();
			
			var domQuirk1Pointers = document.getElementsByTagName("INPUT");

			for(i = 0; i < domQuirk1Pointers.length; i++)
			{
				if(domQuirk1Pointers[i].id == "") domQuirk1Pointers[i].id = "auto_generated_id" + i
				domQuirk1IDs[i] = domQuirk1Pointers[i].id;
				domQuirk1Values[i] = domQuirk1Pointers[i].value;
				domQuirk1Checked[i] = domQuirk1Pointers[i].checked;
				domQuirk1Pointers[i].value = domQuirk1Pointers[i].value ;
			}
		}
		else
		{
			for(i = 0; i < domQuirk1IDs.length; i++)
			{
				ob = document.getElementById(domQuirk1IDs[i]);
				ob.value = domQuirk1Values[i];
				ob.checked = domQuirk1Checked[i];
			}
		}
		
	}

	function tblInsertTopRowAbove(ob)
	{
		// copies the topmost row and inserts it above the row where the object ob resides

		var row, topRow, newRow, temp, i;

		if(ob.tagName=="TR") row = ob;
		else row = tblGetMyRow(ob);

		var siblings = domGetChildrenByTagName(row.parentNode, "TR");

		newRow = siblings[0].cloneNode(true);

		// Prevent duplicate ID's in the document, after copying a row
		temp = newRow.getElementsByTagName('*');
		for(i = 0; i < temp.length; i++)
		{
			if(temp[i].id) 
			{
				temp[i].id = "auto_generated_id"+Math.floor(Math.random()*10000000);
			}
		}

		// insert before this row, unless previous row is hidden. If it is hidden, insert before the hidden row instead

		if(row.previousSibling && row.previousSibling.previousSibling && row.previousSibling.style.display=="none")
			row.parentNode.insertBefore(newRow, row.previousSibling);
		else
			row.parentNode.insertBefore(newRow, row);
		newRow.style.display = '';
	}

	function tblRowMoveDown(ob) // accepts any object laying within a table row (tr) as well as the tr object
	{
		domQuirkValues(true);
		if(ob.tagName=="TR") row = ob;
		else row = tblGetMyRow(ob);

		if(nextRow = row.nextSibling && nextRow.style.display!="none")
		{
			row.parentNode.insertBefore(nextRow,row);
		}
		domQuirkValues(false);
	}

	function tblRowMoveUp(ob)
	{
		domQuirkValues(true);
		var row = tblGetMyRow(ob);
		var prevRow = row.previousSibling;
		if(prevRow && prevRow.style.display!="none")
		{
			row.parentNode.insertBefore(row,prevRow);
		}
		domQuirkValues(false);
	}

	function tblRowDelete(ob)
	{
		var row = tblGetMyRow(ob);
		row.parentNode.removeChild(row);
	}

	function tblGetMyRow(ob)
	{
		var row = ob;
		while(row = row.parentNode)
			if(row.tagName=="TR") return row;

		return false;
	}

	function domGetChildrenByTagName(ob, tagName)
	{ // get all children of a particular tagname, laying directly below ob in the hierarchy
		var res = new Array();
		var i;

		if(ob.childNodes) for(i = 0; i < ob.childNodes.length; i++)
		{
			if(ob.childNodes[i].tagName==tagName) 
				res[res.length] = ob.childNodes[i];
		}

		return res;
	}

	function domInsertParent(child, parent)
	{
		child.parentNode.insertBefore(parent, child);
		parent.appendChild(child);
	}

	function serializeTable(table, takeInnerHTML)
	{
		var res;
		var cols;
		var rows;
		var colAdder = 0;
		var partElements;
		var parts = new Array("THEAD","TBODY","TFOOT");


		res = new Array();

		for(p = 0; p < parts.length; p++)
		{
			partElements = domGetChildrenByTagName(table, parts[p]);
			if(partElements.length>0)
			{
				part = partElements[0];
				rows = domGetChildrenByTagName(part, "TR");

				for(r = 0; r < rows.length; r++)
				{
					res[r] = new Array();
					cols = domGetChildrenByTagName(rows[r], "TD");

					colAdder = 0;
					for(c = 0; c < cols.length; c++)
					{
						if(takeInnerHTML)
						{
							res[r][c] = cols[c].innerHTML;
						}
						else
						{
							for(i = 0; i < cols[c].childNodes.length; i++)
							{
								if(cols[c].childNodes[i].value !== undefined) 
								{
									if(cols[c].childNodes[i].type == "checkbox")
									{
										res[r][colAdder++] = cols[c].childNodes[i].checked;
									}
									else if(cols[c].childNodes[i].type == "radio")
									{
										if(cols[c].childNodes[i].checked) res[r][colAdder++] = cols[c].childNodes[i].value;
									}
									else
										res[r][colAdder++] = cols[c].childNodes[i].value;
								}
							}
						}
					}
				}
			}
		}
		return res;
	}
