

if (dwr == null)
	var dwr = {};
if (dwr.util == null)
	dwr.util = {};
if (DWRUtil == null)
	var DWRUtil = dwr.util;

dwr.util._escapeHtml = true;

dwr.util.setEscapeHtml = function(escapeHtml) {
	dwr.util._escapeHtml = escapeHtml;
};

dwr.util._shouldEscapeHtml = function(options) {
	if (options && options.escapeHtml != null) {
		return options.escapeHtml;
	}
	return dwr.util._escapeHtml;
};

dwr.util.escapeHtml = function(original) {
	var div = document.createElement('div');
	var text = document.createTextNode(original);
	div.appendChild(text);
	return div.innerHTML;
};

dwr.util.unescapeHtml = function(original) {
	var div = document.createElement('div');
	div.innerHTML = original.replace(/<\/?[^>]+>/gi, '');
	return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
};

dwr.util.replaceXmlCharacters = function(original) {
	original = original.replace("&", "+");
	original = original.replace("<", "\u2039");
	original = original.replace(">", "\u203A");
	original = original.replace("\'", "\u2018");
	original = original.replace("\"", "\u201C");
	return original;
};

dwr.util.containsXssRiskyCharacters = function(original) {
	return (original.indexOf('&') != -1 || original.indexOf('<') != -1 || original.indexOf('>') != -1
	|| original.indexOf('\'') != -1 || original.indexOf('\"') != -1);
};

dwr.util.onReturn = function(event, action) {
	if (!event)
		event = window.event;
	if (event && event.keyCode && event.keyCode == 13)
		action();
};

dwr.util.selectRange = function(ele, start, end) {
	ele = dwr.util._getElementById(ele, "selectRange()");
	if (ele == null)
		return;
	if (ele.setSelectionRange) {
		ele.setSelectionRange(start, end);
	} else if (ele.createTextRange) {
		var range = ele.createTextRange();
		range.moveStart("character", start);
		range.moveEnd("character", end - ele.value.length);
		range.select();
	}
	ele.focus();
};

if (document.getElementById) {
	dwr.util.byId = function() {
		var elements = new Array();
		for (var i = 0; i < arguments.length; i++) {
			var element = arguments[i];
			if (typeof element == 'string') {
				element = document.getElementById(element);
			}
			if (arguments.length == 1) {
				return element;
			}
			elements.push(element);
		}
		return elements;
	};
} else if (document.all) {
	dwr.util.byId = function() {
		var elements = new Array();
		for (var i = 0; i < arguments.length; i++) {
			var element = arguments[i];
			if (typeof element == 'string') {
				element = document.all[element];
			}
			if (arguments.length == 1) {
				return element;
			}
			elements.push(element);
		}
		return elements;
	};
}

var $;
if (!$) {
	$ = dwr.util.byId;
}

dwr.util.toDescriptiveString = function(data, showLevels, options) {
	if (showLevels === undefined)
		showLevels = 1;
	var opt = {};
	if (dwr.util._isObject(options))
		opt = options;
	var defaultoptions = {
		escapeHtml : false,
		baseIndent : "",
		childIndent : "\u00A0\u00A0",
		lineTerminator : "\n",
		oneLineMaxItems : 5,
		shortStringMaxLength : 13,
		propertyNameMaxLength : 30
	};
	for (var p in defaultoptions) {
		if (!(p in opt)) {
			opt[p] = defaultoptions[p];
		}
	}

	var skipDomProperties = {
		document : true,
		ownerDocument : true,
		all : true,
		parentElement : true,
		parentNode : true,
		offsetParent : true,
		children : true,
		firstChild : true,
		lastChild : true,
		previousSibling : true,
		nextSibling : true,
		innerHTML : true,
		outerHTML : true,
		innerText : true,
		outerText : true,
		textContent : true,
		attributes : true,
		style : true,
		currentStyle : true,
		runtimeStyle : true,
		parentTextEdit : true
	};

	function recursive(data, showLevels, indentDepth, options) {
		var reply = "";
		try {

			if (typeof data == "string") {
				var str = data;
				if (showLevels == 0 && str.length > options.shortStringMaxLength)
					str = str.substring(0, options.shortStringMaxLength - 3) + "...";
				if (options.escapeHtml) {

					var lines = str.split("\n");
					for (var i = 0; i < lines.length; i++)
						lines[i] = dwr.util.escapeHtml(lines[i]);
					str = lines.join("\n");
				}
				if (showLevels == 0) {
					str = str.replace(/\n|\r|\t/g, function(ch) {
						switch (ch) {
							case "\n" :
								return "\\n";
							case "\r" :
								return "";
							case "\t" :
								return "\\t";
						}
					});
				} else {
					str = str.replace(/\n|\r|\t/g, function(ch) {
						switch (ch) {
							case "\n" :
								return options.lineTerminator + indent(indentDepth + 1, options);
							case "\r" :
								return "";
							case "\t" :
								return "\\t";
						}
					});
				}
				reply = '"' + str + '"';
			}

			else if (typeof data == "function") {
				reply = "function";
			}

			else if (dwr.util._isArray(data)) {
				if (showLevels == 0) {
					if (data.length > 0)
						reply = "[...]";
					else
						reply = "[]";
				} else {
					var strarr = [];
					strarr.push("[");
					var count = 0;
					for (var i = 0; i < data.length; i++) {
						if (!(i in data))
							continue;
						var itemvalue = data[i];
						if (count > 0)
							strarr.push(", ");
						if (showLevels == 1) {
							if (count == options.oneLineMaxItems) {
								strarr.push("...");
								break;
							}
						} else {
							strarr.push(options.lineTerminator + indent(indentDepth + 1, options));
						}
						if (i != count) {
							strarr.push(i);
							strarr.push(":");
						}
						strarr.push(recursive(itemvalue, showLevels - 1, indentDepth + 1, options));
						count++;
					}
					if (showLevels > 1)
						strarr.push(options.lineTerminator + indent(indentDepth, options));
					strarr.push("]");
					reply = strarr.join("");
				}
			}

			else if (dwr.util._isObject(data) && !dwr.util._isDate(data)) {
				if (showLevels == 0) {
					reply = dwr.util._detailedTypeOf(data);
				} else {
					var strarr = [];
					if (dwr.util._detailedTypeOf(data) != "Object") {
						strarr.push(dwr.util._detailedTypeOf(data));
						if (typeof data.valueOf() != "object") {
							strarr.push(":");
							strarr.push(recursive(data.valueOf(), 1, indentDepth, options));
						}
						strarr.push(" ");
					}
					strarr.push("{");
					var isDomObject = dwr.util._isHTMLElement(data);
					var count = 0;
					for (var prop in data) {
						var propvalue = data[prop];
						if (isDomObject) {
							if (!propvalue)
								continue;
							if (typeof propvalue == "function")
								continue;
							if (skipDomProperties[prop])
								continue;
							if (prop.toUpperCase() == prop)
								continue;
						}
						if (count > 0)
							strarr.push(", ");
						if (showLevels == 1) {
							if (count == options.oneLineMaxItems) {
								strarr.push("...");
								break;
							}
						} else {
							strarr.push(options.lineTerminator + indent(indentDepth + 1, options));
						}
						strarr.push(prop.length > options.propertyNameMaxLength ? prop.substring(0,
						options.propertyNameMaxLength - 3)
						+ "..." : prop);
						strarr.push(":");
						strarr.push(recursive(propvalue, showLevels - 1, indentDepth + 1, options));
						count++;
					}
					if (showLevels > 1 && count > 0)
						strarr.push(options.lineTerminator + indent(indentDepth, options));
					strarr.push("}");
					reply = strarr.join("");
				}
			}

			else {
				reply = "" + data;
			}

			return reply;
		} catch (err) {
			return (err.message ? err.message : "" + err);
		}
	}

	function indent(count, options) {
		var strarr = [];
		strarr.push(options.baseIndent);
		for (var i = 0; i < count; i++) {
			strarr.push(options.childIndent);
		}
		return strarr.join("");
	};

	return recursive(data, showLevels, 0, opt);
};

dwr.util.useLoadingMessage = function(message) {
	var loadingMessage;
	if (message)
		loadingMessage = message;
	else
		loadingMessage = "Loading";
	dwr.engine.setPreHook(function() {
		var disabledZone = dwr.util.byId('disabledZone');
		if (!disabledZone) {
			disabledZone = document.createElement('div');
			disabledZone.setAttribute('id', 'disabledZone');
			disabledZone.style.position = "absolute";
			disabledZone.style.zIndex = "1000";
			disabledZone.style.left = "0px";
			disabledZone.style.top = "0px";
			disabledZone.style.width = "100%";
			disabledZone.style.height = "100%";
			document.body.appendChild(disabledZone);
			var messageZone = document.createElement('div');
			messageZone.setAttribute('id', 'messageZone');
			messageZone.style.position = "absolute";
			messageZone.style.top = "0px";
			messageZone.style.right = "0px";
			messageZone.style.background = "red";
			messageZone.style.color = "white";
			messageZone.style.fontFamily = "Arial,Helvetica,sans-serif";
			messageZone.style.padding = "4px";
			disabledZone.appendChild(messageZone);
			var text = document.createTextNode(loadingMessage);
			messageZone.appendChild(text);
			dwr.util._disabledZoneUseCount = 1;
		} else {
			dwr.util.byId('messageZone').innerHTML = loadingMessage;
			disabledZone.style.visibility = 'visible';
			dwr.util._disabledZoneUseCount++;
		}
	});
	dwr.engine.setPostHook(function() {
		dwr.util._disabledZoneUseCount--;
		if (dwr.util._disabledZoneUseCount == 0) {
			dwr.util.byId('disabledZone').style.visibility = 'hidden';
		}
	});
};

dwr.util.setHighlightHandler = function(handler) {
	dwr.util._highlightHandler = handler;
};

dwr.util.yellowFadeHighlightHandler = function(ele) {
	dwr.util._yellowFadeProcess(ele, 0);
};
dwr.util._yellowFadeSteps = ["d0", "b0", "a0", "90", "98", "a0", "a8", "b0", "b8", "c0", "c8", "d0", "d8", "e0", "e8",
"f0", "f8"];
dwr.util._yellowFadeProcess = function(ele, colorIndex) {
	ele = dwr.util.byId(ele);
	if (colorIndex < dwr.util._yellowFadeSteps.length) {
		ele.style.backgroundColor = "#ffff" + dwr.util._yellowFadeSteps[colorIndex];
		setTimeout("dwr.util._yellowFadeProcess('" + ele.id + "'," + (colorIndex + 1) + ")", 200);
	} else {
		ele.style.backgroundColor = "transparent";
	}
};

dwr.util.borderFadeHighlightHandler = function(ele) {
	ele.style.borderWidth = "2px";
	ele.style.borderStyle = "solid";
	dwr.util._borderFadeProcess(ele, 0);
};
dwr.util._borderFadeSteps = ["d0", "b0", "a0", "90", "98", "a0", "a8", "b0", "b8", "c0", "c8", "d0", "d8", "e0", "e8",
"f0", "f8"];
dwr.util._borderFadeProcess = function(ele, colorIndex) {
	ele = dwr.util.byId(ele);
	if (colorIndex < dwr.util._borderFadeSteps.length) {
		ele.style.borderColor = "#ff" + dwr.util._borderFadeSteps[colorIndex] + dwr.util._borderFadeSteps[colorIndex];
		setTimeout("dwr.util._borderFadeProcess('" + ele.id + "'," + (colorIndex + 1) + ")", 200);
	} else {
		ele.style.backgroundColor = "transparent";
	}
};

dwr.util.focusHighlightHandler = function(ele) {
	try {
		ele.focus();
	} catch (ex) {
	}
};

dwr.util._highlightHandler = null;

dwr.util.highlight = function(ele, options) {
	if (options && options.highlightHandler) {
		options.highlightHandler(dwr.util.byId(ele));
	} else if (dwr.util._highlightHandler != null) {
		dwr.util._highlightHandler(dwr.util.byId(ele));
	}
};

dwr.util.setValue = function(ele, val, options) {
	if (val == null)
		val = "";
	if (options == null)
		options = {};

	var orig = ele;
	if (typeof ele == "string") {
		ele = dwr.util.byId(ele);

		if (ele && ele.id != orig)
			ele = null;
	}
	var nodes = null;
	if (ele == null) {

		nodes = document.getElementsByName(orig);
		if (nodes.length >= 1)
			ele = nodes.item(0);
	}

	if (ele == null) {
		dwr.util._debug("setValue() can't find an element with id/name: " + orig + ".");
		return;
	}

	dwr.util.highlight(ele, options);

	if (dwr.util._isHTMLElement(ele, "select")) {
		if (ele.type == "select-multiple" && dwr.util._isArray(val))
			dwr.util._selectListItems(ele, val);
		else
			dwr.util._selectListItem(ele, val);
		return;
	}

	if (dwr.util._isHTMLElement(ele, "input")) {
		if (ele.type == "radio" || ele.type == "checkbox") {
			if (nodes && nodes.length >= 1) {
				for (var i = 0; i < nodes.length; i++) {
					var node = nodes.item(i);
					if (node.type != ele.type)
						continue;
					if (dwr.util._isArray(val)) {
						node.checked = false;
						for (var j = 0; j < val.length; j++)
							if (val[j] == node.value)
								node.checked = true;
					} else {
						node.checked = (node.value == val);
					}
				}
			} else {
				ele.checked = (val == true);
			}
		} else
			ele.value = val;

		return;
	}

	if (dwr.util._isHTMLElement(ele, "textarea")) {
		ele.value = val;
		return;
	}

	if (val.nodeType) {
		if (val.nodeType == 9)
			val = val.documentElement;
		val = dwr.util._importNode(ele.ownerDocument, val, true);
		ele.appendChild(val);
		return;
	}

	if (dwr.util._shouldEscapeHtml(options) && typeof(val) == "string") {
		if (ele.textContent)
			ele.textContent = val;
		else if (ele.innerText)
			ele.innerText = val;
		else
			ele.innerHTML = dwr.util.escapeHtml(val);
	} else {
		ele.innerHTML = val;
	}
};

dwr.util._selectListItems = function(ele, val) {

	var found = false;
	var i;
	var j;
	for (i = 0; i < ele.options.length; i++) {
		ele.options[i].selected = false;
		for (j = 0; j < val.length; j++) {
			if (ele.options[i].value == val[j]) {
				ele.options[i].selected = true;
			}
		}
	}

	if (found)
		return;

	for (i = 0; i < ele.options.length; i++) {
		for (j = 0; j < val.length; j++) {
			if (ele.options[i].text == val[j]) {
				ele.options[i].selected = true;
			}
		}
	}
};

dwr.util._selectListItem = function(ele, val) {

	var found = false;
	var i;
	for (i = 0; i < ele.options.length; i++) {
		if (ele.options[i].value == val) {
			ele.options[i].selected = true;
			found = true;
		} else {
			ele.options[i].selected = false;
		}
	}

	if (found)
		return;

	for (i = 0; i < ele.options.length; i++) {
		ele.options[i].selected = (ele.options[i].text == val);
	}
};

dwr.util.getValue = function(ele, options) {
	if (options == null)
		options = {};
	var orig = ele;
	if (typeof ele == "string") {
		ele = dwr.util.byId(ele);

		if (ele && ele.id != orig)
			ele = null;
	}
	var nodes = null;
	if (ele == null) {

		nodes = document.getElementsByName(orig);
		if (nodes.length >= 1)
			ele = nodes.item(0);
	}
	if (ele == null) {
		dwr.util._debug("getValue() can't find an element with id/name: " + orig + ".");
		return "";
	}

	if (dwr.util._isHTMLElement(ele, "select")) {

		if (ele.type == "select-multiple") {
			var reply = new Array();
			for (var i = 0; i < ele.options.length; i++) {
				var item = ele.options[i];
				if (item.selected) {
					var valueAttr = item.getAttributeNode("value");
					if (valueAttr && valueAttr.specified) {
						reply.push(item.value);
					} else {
						reply.push(item.text);
					}
				}
			}
			return reply;
		} else {
			var sel = ele.selectedIndex;
			if (sel != -1) {
				var item = ele.options[sel];
				var valueAttr = item.getAttributeNode("value");
				if (valueAttr && valueAttr.specified) {
					return item.value;
				}
				return item.text;
			} else {
				return "";
			}
		}
	}

	if (dwr.util._isHTMLElement(ele, "input")) {
		if (ele.type == "radio") {
			if (nodes && nodes.length >= 1) {
				for (var i = 0; i < nodes.length; i++) {
					var node = nodes.item(i);
					if (node.type == ele.type) {
						if (node.checked)
							return node.value;
					}
				}
			}
			return ele.checked;
		}
		if (ele.type == "checkbox") {
			if (nodes && nodes.length >= 1) {
				var reply = [];
				for (var i = 0; i < nodes.length; i++) {
					var node = nodes.item(i);
					if (node.type == ele.type) {
						if (node.checked)
							reply.push(node.value);
					}
				}
				return reply;
			}
			return ele.checked;
		}
		return ele.value;
	}

	if (dwr.util._isHTMLElement(ele, "textarea")) {
		return ele.value;
	}

	if (dwr.util._shouldEscapeHtml(options)) {
		if (ele.textContent)
			return ele.textContent;
		else if (ele.innerText)
			return ele.innerText;
	}
	return ele.innerHTML;
};

dwr.util.getText = function(ele) {
	ele = dwr.util._getElementById(ele, "getText()");
	if (ele == null)
		return null;
	if (!dwr.util._isHTMLElement(ele, "select")) {
		dwr.util._debug("getText() can only be used with select elements. Attempt to use: "
		+ dwr.util._detailedTypeOf(ele) + " from  id: " + orig + ".");
		return "";
	}

	var sel = ele.selectedIndex;
	if (sel != -1) {
		return ele.options[sel].text;
	} else {
		return "";
	}
};

dwr.util.setValues = function(data, options) {
	var prefix = "";
	if (options && options.prefix)
		prefix = options.prefix;
	if (options && options.idPrefix)
		prefix = options.idPrefix;
	dwr.util._setValuesRecursive(data, prefix);
};

dwr.util._setValuesRecursive = function(data, idpath) {

	if (dwr.util._isArray(data) && data.length > 0 && dwr.util._isObject(data[0])) {
		for (var i = 0; i < data.length; i++) {
			dwr.util._setValuesRecursive(data[i], idpath + "[" + i + "]");
		}
	}

	else if (dwr.util._isObject(data) && !dwr.util._isArray(data)) {
		for (var prop in data) {
			var subidpath = idpath ? idpath + "." + prop : prop;

			if (dwr.util._isObject(data[prop]) && !dwr.util._isArray(data[prop]) || dwr.util._isArray(data[prop])
			&& data[prop].length > 0 && dwr.util._isObject(data[prop][0])) {
				dwr.util._setValuesRecursive(data[prop], subidpath);
			}

			else if (typeof data[prop] == "function") {

			}

			else {

				if (dwr.util.byId(subidpath) != null || document.getElementsByName(subidpath).length >= 1) {
					dwr.util.setValue(subidpath, data[prop]);
				}
			}
		}
	}
};

dwr.util.getValues = function(data, options) {
	if (typeof data == "string" || dwr.util._isHTMLElement(data)) {
		return dwr.util.getFormValues(data);
	} else {
		var prefix = "";
		if (options != null && options.prefix)
			prefix = options.prefix;
		if (options != null && options.idPrefix)
			prefix = options.idPrefix;
		dwr.util._getValuesRecursive(data, prefix);
		return data;
	}
};

dwr.util.getFormValues = function(eleOrNameOrId) {
	var ele = null;
	if (typeof eleOrNameOrId == "string") {
		ele = document.forms[eleOrNameOrId];
		if (ele == null)
			ele = dwr.util.byId(eleOrNameOrId);
	} else if (dwr.util._isHTMLElement(eleOrNameOrId)) {
		ele = eleOrNameOrId;
	}
	if (ele != null) {
		if (ele.elements == null) {
			alert("getFormValues() requires an object or reference to a form element.");
			return null;
		}
		var reply = {};
		var name;
		var value;
		for (var i = 0; i < ele.elements.length; i++) {
			if (ele[i].type in {
				button : 0,
				submit : 0,
				reset : 0,
				image : 0,
				file : 0
			})
				continue;
			if (ele[i].name) {
				name = ele[i].name;
				value = dwr.util.getValue(name);
			} else {
				if (ele[i].id)
					name = ele[i].id;
				else
					name = "element" + i;
				value = dwr.util.getValue(ele[i]);
			}
			reply[name] = value;
		}
		return reply;
	}
};

dwr.util._getValuesRecursive = function(data, idpath) {

	if (dwr.util._isArray(data) && data.length > 0 && dwr.util._isObject(data[0])) {
		for (var i = 0; i < data.length; i++) {
			dwr.util._getValuesRecursive(data[i], idpath + "[" + i + "]");
		}
	}

	else if (dwr.util._isObject(data) && !dwr.util._isArray(data)) {
		for (var prop in data) {
			var subidpath = idpath ? idpath + "." + prop : prop;

			if (dwr.util._isObject(data[prop]) && !dwr.util._isArray(data[prop]) || dwr.util._isArray(data[prop])
			&& data[prop].length > 0 && dwr.util._isObject(data[prop][0])) {
				dwr.util._getValuesRecursive(data[prop], subidpath);
			}

			else if (typeof data[prop] == "function") {

			}

			else {

				if (dwr.util.byId(subidpath) != null || document.getElementsByName(subidpath).length >= 1) {
					data[prop] = dwr.util.getValue(subidpath);
				}
			}
		}
	}
};

dwr.util.addOptions = function(ele, data) {
	ele = dwr.util._getElementById(ele, "addOptions()");
	if (ele == null)
		return;
	var useOptions = dwr.util._isHTMLElement(ele, "select");
	var useLi = dwr.util._isHTMLElement(ele, ["ul", "ol"]);
	if (!useOptions && !useLi) {
		dwr.util._debug("addOptions() can only be used with select/ul/ol elements. Attempt to use: "
		+ dwr.util._detailedTypeOf(ele));
		return;
	}
	if (data == null)
		return;

	var argcount = arguments.length;
	var options = {};
	var lastarg = arguments[argcount - 1];
	if (argcount > 2 && dwr.util._isObject(lastarg)) {
		options = lastarg;
		argcount--;
	}
	var arg3 = null;
	if (argcount >= 3)
		arg3 = arguments[2];
	var arg4 = null;
	if (argcount >= 4)
		arg4 = arguments[3];
	if (!options.optionCreator && useOptions)
		options.optionCreator = dwr.util._defaultOptionCreator;
	if (!options.optionCreator && useLi)
		options.optionCreator = dwr.util._defaultListItemCreator;

	var text, value, li;
	if (dwr.util._isArray(data)) {

		for (var i = 0; i < data.length; i++) {
			options.data = data[i];
			options.text = null;
			options.value = null;
			if (useOptions) {
				if (arg3 != null) {
					if (arg4 != null) {
						options.text = dwr.util._getValueFrom(data[i], arg4);
						options.value = dwr.util._getValueFrom(data[i], arg3);
					} else
						options.text = options.value = dwr.util._getValueFrom(data[i], arg3);
				} else
					options.text = options.value = dwr.util._getValueFrom(data[i]);

				if (options.text != null || options.value) {
					var opt = options.optionCreator(options);
					opt.text = options.text;
					opt.value = options.value;
					ele.options[ele.options.length] = opt;
				}
			} else {
				options.value = dwr.util._getValueFrom(data[i], arg3);
				if (options.value != null) {
					li = options.optionCreator(options);
					if (dwr.util._shouldEscapeHtml(options)) {
						options.value = dwr.util.escapeHtml(options.value);
					}
					li.innerHTML = options.value;
					ele.appendChild(li);
				}
			}
		}
	} else if (arg4 != null) {
		if (!useOptions) {
			alert("dwr.util.addOptions can only create select lists from objects.");
			return;
		}
		for (var prop in data) {
			options.data = data[prop];
			options.value = dwr.util._getValueFrom(data[prop], arg3);
			options.text = dwr.util._getValueFrom(data[prop], arg4);

			if (options.text != null || options.value) {
				var opt = options.optionCreator(options);
				opt.text = options.text;
				opt.value = options.value;
				ele.options[ele.options.length] = opt;
			}
		}
	} else {
		if (!useOptions) {
			dwr.util._debug("dwr.util.addOptions can only create select lists from objects.");
			return;
		}
		for (var prop in data) {
			if (typeof data[prop] == "function")
				continue;
			options.data = data[prop];
			if (!arg3) {
				options.value = prop;
				options.text = data[prop];
			} else {
				options.value = data[prop];
				options.text = prop;
			}
			if (options.text != null || options.value) {
				var opt = options.optionCreator(options);
				opt.text = options.text;
				opt.value = options.value;
				ele.options[ele.options.length] = opt;
			}
		}
	}

	dwr.util.highlight(ele, options);
};

dwr.util._getValueFrom = function(data, method) {
	if (method == null)
		return data;
	else if (typeof method == 'function')
		return method(data);
	else
		return data[method];
};

dwr.util._defaultOptionCreator = function(options) {
	return new Option();
};

dwr.util._defaultListItemCreator = function(options) {
	return document.createElement("li");
};

dwr.util.removeAllOptions = function(ele) {
	ele = dwr.util._getElementById(ele, "removeAllOptions()");
	if (ele == null)
		return;
	var useOptions = dwr.util._isHTMLElement(ele, "select");
	var useLi = dwr.util._isHTMLElement(ele, ["ul", "ol"]);
	if (!useOptions && !useLi) {
		dwr.util._debug("removeAllOptions() can only be used with select, ol and ul elements. Attempt to use: "
		+ dwr.util._detailedTypeOf(ele));
		return;
	}
	if (useOptions) {
		ele.options.length = 0;
	} else {
		while (ele.childNodes.length > 0) {
			ele.removeChild(ele.firstChild);
		}
	}
};

dwr.util.addRows = function(ele, data, cellFuncs, options) {
	ele = dwr.util._getElementById(ele, "addRows()");
	if (ele == null)
		return;
	if (!dwr.util._isHTMLElement(ele, ["table", "tbody", "thead", "tfoot"])) {
		dwr.util._debug("addRows() can only be used with table, tbody, thead and tfoot elements. Attempt to use: "
		+ dwr.util._detailedTypeOf(ele));
		return;
	}
	if (!options)
		options = {};
	if (!options.rowCreator)
		options.rowCreator = dwr.util._defaultRowCreator;
	if (!options.cellCreator)
		options.cellCreator = dwr.util._defaultCellCreator;
	var tr, rowNum;
	if (dwr.util._isArray(data)) {
		for (rowNum = 0; rowNum < data.length; rowNum++) {
			options.rowData = data[rowNum];
			options.rowIndex = rowNum;
			options.rowNum = rowNum;
			options.data = null;
			options.cellNum = -1;
			tr = dwr.util._addRowInner(cellFuncs, options);
			if (tr != null)
				ele.appendChild(tr);
		}
	} else if (typeof data == "object") {
		rowNum = 0;
		for (var rowIndex in data) {
			options.rowData = data[rowIndex];
			options.rowIndex = rowIndex;
			options.rowNum = rowNum;
			options.data = null;
			options.cellNum = -1;
			tr = dwr.util._addRowInner(cellFuncs, options);
			if (tr != null)
				ele.appendChild(tr);
			rowNum++;
		}
	}

	dwr.util.highlight(ele, options);
};

dwr.util._addRowInner = function(cellFuncs, options) {
	var tr = options.rowCreator(options);
	if (tr == null)
		return null;
	for (var cellNum = 0; cellNum < cellFuncs.length; cellNum++) {
		var func = cellFuncs[cellNum];
		if (typeof func == 'function')
			options.data = func(options.rowData, options);
		else
			options.data = func || "";
		options.cellNum = cellNum;
		var td = options.cellCreator(options);
		if (td != null) {
			if (options.data != null) {
				if (dwr.util._isHTMLElement(options.data))
					td.appendChild(options.data);
				else {
					if (dwr.util._shouldEscapeHtml(options) && typeof(options.data) == "string") {
						td.innerHTML = dwr.util.escapeHtml(options.data);
					} else {
						td.innerHTML = options.data;
					}
				}
			}
			tr.appendChild(td);
		}
	}
	return tr;
};

dwr.util._defaultRowCreator = function(options) {
	return document.createElement("tr");
};

dwr.util._defaultCellCreator = function(options) {
	return document.createElement("td");
};

dwr.util.removeAllRows = function(ele, options) {
	ele = dwr.util._getElementById(ele, "removeAllRows()");
	if (ele == null)
		return;
	if (!options)
		options = {};
	if (!options.filter)
		options.filter = function() {
			return true;
		};
	if (!dwr.util._isHTMLElement(ele, ["table", "tbody", "thead", "tfoot"])) {
		dwr.util
		._debug("removeAllRows() can only be used with table, tbody, thead and tfoot elements. Attempt to use: "
		+ dwr.util._detailedTypeOf(ele));
		return;
	}
	var child = ele.firstChild;
	var next;
	while (child != null) {
		next = child.nextSibling;
		if (options.filter(child)) {
			ele.removeChild(child);
		}
		child = next;
	}
};

dwr.util.setClassName = function(ele, className) {
	ele = dwr.util._getElementById(ele, "setClassName()");
	if (ele == null)
		return;
	ele.className = className;
};

dwr.util.addClassName = function(ele, className) {
	ele = dwr.util._getElementById(ele, "addClassName()");
	if (ele == null)
		return;
	ele.className += " " + className;
};

dwr.util.removeClassName = function(ele, className) {
	ele = dwr.util._getElementById(ele, "removeClassName()");
	if (ele == null)
		return;
	var regex = new RegExp("(^|\\s)" + className + "(\\s|$)", 'g');
	ele.className = ele.className.replace(regex, '');
};

dwr.util.toggleClassName = function(ele, className) {
	ele = dwr.util._getElementById(ele, "toggleClassName()");
	if (ele == null)
		return;
	var regex = new RegExp("(^|\\s)" + className + "(\\s|$)");
	if (regex.test(ele.className)) {
		ele.className = ele.className.replace(regex, '');
	} else {
		ele.className += " " + className;
	}
};

dwr.util.cloneNode = function(ele, options) {
	ele = dwr.util._getElementById(ele, "cloneNode()");
	if (ele == null)
		return null;
	if (options == null)
		options = {};
	var clone = ele.cloneNode(true);
	if (options.idPrefix || options.idSuffix) {
		dwr.util._updateIds(clone, options);
	} else {
		dwr.util._removeIds(clone);
	}
	ele.parentNode.insertBefore(clone, ele);
	return clone;
};

dwr.util._updateIds = function(ele, options) {
	if (options == null)
		options = {};
	if (ele.id) {
		ele.setAttribute("id", (options.idPrefix || "") + ele.id + (options.idSuffix || ""));
	}
	var children = ele.childNodes;
	for (var i = 0; i < children.length; i++) {
		var child = children.item(i);
		if (child.nodeType == 1) {
			dwr.util._updateIds(child, options);
		}
	}
};

dwr.util._removeIds = function(ele) {
	if (ele.id)
		ele.removeAttribute("id");
	var children = ele.childNodes;
	for (var i = 0; i < children.length; i++) {
		var child = children.item(i);
		if (child.nodeType == 1) {
			dwr.util._removeIds(child);
		}
	}
};

dwr.util.cloneNodeForValues = function(templateEle, data, options) {
	templateEle = dwr.util._getElementById(templateEle, "cloneNodeForValues()");
	if (templateEle == null)
		return null;
	if (options == null)
		options = {};
	var idpath;
	if (options.idPrefix != null)
		idpath = options.idPrefix;
	else
		idpath = templateEle.id || "";
	return dwr.util._cloneNodeForValuesRecursive(templateEle, data, idpath, options);
};

dwr.util._cloneNodeForValuesRecursive = function(templateEle, data, idpath, options) {

	if (dwr.util._isArray(data)) {
		var clones = [];
		for (var i = 0; i < data.length; i++) {
			var item = data[i];
			var clone = dwr.util._cloneNodeForValuesRecursive(templateEle, item, idpath + "[" + i + "]", options);
			clones.push(clone);
		}
		return clones;
	} else

	if (dwr.util._isObject(data) && !dwr.util._isArray(data)) {
		var clone = templateEle.cloneNode(true);
		if (options.updateCloneStyle && clone.style) {
			for (var propname in options.updateCloneStyle) {
				clone.style[propname] = options.updateCloneStyle[propname];
			}
		}
		dwr.util._replaceIds(clone, templateEle.id, idpath);
		templateEle.parentNode.insertBefore(clone, templateEle);
		dwr.util._cloneSubArrays(data, idpath, options);
		return clone;
	}

	return null;
};

dwr.util._replaceIds = function(ele, oldidpath, newidpath) {
	if (ele.id) {
		var newId = null;
		if (ele.id == oldidpath) {
			newId = newidpath;
		} else if (ele.id.length > oldidpath.length) {
			if (ele.id.substr(0, oldidpath.length) == oldidpath) {
				var trailingChar = ele.id.charAt(oldidpath.length);
				if (trailingChar == "." || trailingChar == "[") {
					newId = newidpath + ele.id.substr(oldidpath.length);
				}
			}
		}
		if (newId) {
			ele.setAttribute("id", newId);
		} else {
			ele.removeAttribute("id");
		}
	}
	var children = ele.childNodes;
	for (var i = 0; i < children.length; i++) {
		var child = children.item(i);
		if (child.nodeType == 1) {
			dwr.util._replaceIds(child, oldidpath, newidpath);
		}
	}
};

dwr.util._cloneSubArrays = function(data, idpath, options) {
	for (prop in data) {
		var value = data[prop];

		if (dwr.util._isArray(value)) {

			if (value.length > 0 && dwr.util._isObject(value[0])) {
				var subTemplateId = idpath + "." + prop;
				var subTemplateEle = dwr.util.byId(subTemplateId);
				if (subTemplateEle != null) {
					dwr.util._cloneNodeForValuesRecursive(subTemplateEle, value, subTemplateId, options);
				}
			}
		}

		else if (dwr.util._isObject(value)) {
			dwr.util._cloneSubArrays(value, idpath + "." + prop, options);
		}
	}
};

dwr.util._getElementById = function(ele, source) {
	var orig = ele;
	ele = dwr.util.byId(ele);
	if (ele == null) {
		dwr.util._debug(source + " can't find an element with id: " + orig + ".");
	}
	return ele;
};

dwr.util._isHTMLElement = function(ele, nodeName) {
	if (ele == null || typeof ele != "object" || ele.nodeName == null) {
		return false;
	}
	if (nodeName != null) {
		var test = ele.nodeName.toLowerCase();
		if (typeof nodeName == "string") {
			return test == nodeName.toLowerCase();
		}
		if (dwr.util._isArray(nodeName)) {
			var match = false;
			for (var i = 0; i < nodeName.length && !match; i++) {
				if (test == nodeName[i].toLowerCase()) {
					match = true;
				}
			}
			return match;
		}
		dwr.util
		._debug("dwr.util._isHTMLElement was passed test node name that is neither a string or array of strings");
		return false;
	}
	return true;
};

dwr.util._detailedTypeOf = function(x) {
	var reply = typeof x;
	if (reply == "object") {
		reply = Object.prototype.toString.apply(x);
		reply = reply.substring(8, reply.length - 1);
	}
	return reply;
};

dwr.util._isObject = function(data) {
	return (data && typeof data == "object");
};

dwr.util._isArray = function(data) {
	return (data && data.join);
};

dwr.util._isDate = function(data) {
	return (data && data.toUTCString) ? true : false;
};

dwr.util._importNode = function(doc, importedNode, deep) {
	var newNode;

	if (importedNode.nodeType == 1) {
		newNode = doc.createElement(importedNode.nodeName);

		for (var i = 0; i < importedNode.attributes.length; i++) {
			var attr = importedNode.attributes[i];
			if (attr.nodeValue != null && attr.nodeValue != '') {
				newNode.setAttribute(attr.name, attr.nodeValue);
			}
		}

		if (typeof importedNode.style != "undefined") {
			newNode.style.cssText = importedNode.style.cssText;
		}
	} else if (importedNode.nodeType == 3) {
		newNode = doc.createTextNode(importedNode.nodeValue);
	}

	if (deep && importedNode.hasChildNodes()) {
		for (i = 0; i < importedNode.childNodes.length; i++) {
			newNode.appendChild(dwr.util._importNode(doc, importedNode.childNodes[i], true));
		}
	}

	return newNode;
};

dwr.util._debug = function(message, stacktrace) {
	var written = false;
	try {
		if (window.console) {
			if (stacktrace && window.console.trace)
				window.console.trace();
			window.console.log(message);
			written = true;
		} else if (window.opera && window.opera.postError) {
			window.opera.postError(message);
			written = true;
		}
	} catch (ex) {
	}

	if (!written) {
		var debug = document.getElementById("dwr-debug");
		if (debug) {
			var contents = message + "<br/>" + debug.innerHTML;
			if (contents.length > 2048)
				contents = contents.substring(0, 2048);
			debug.innerHTML = contents;
		}
	}
};

