function mmGroupedPreFunction(target, rows) {
	try {
		// store original rows
		target.originalRows = rows;
		// generate tree
		var root = new MMNode("", "", target.value);
		var sRows = rows;
		for (var z = 0; z < sRows.length; z++) {
			var node = new MMNode(sRows[z][0], sRows[z][1], sRows[z][0]);
			node.row = sRows[z];
			if ((target.parameters.flags & AS_GROUPED) == AS_GROUPED)
				root.group(node);
			else 
			if ((target.parameters.flags & AS_GROUPED_DISPLAYCAT) == AS_GROUPED_DISPLAYCAT)
				root.groupDisplayCat(node);
		}
		var result = new Array();
		// don't display root node?
		if ((target.parameters.flags & AS_NO_ROOT) == AS_NO_ROOT) {
			root.levelUp();
			for (var i = 0; i < root.children.length; i++) {
				root.children[i].parent = null;
			}
			root.getAsArray(result);
			result.shift();
		} else {
			root.getAsArray(result);
		}		
		return result;
		
	} catch (E) {
		if (target.parameters.debug)
			alert("groupedPreFunction error: " + E);
	}
}
	
function mmGroupedRowFunction(target, rowArray, field_index, row, iDiv) {
	try {
		var node = rowArray[row][2];
		var value = node.label;
		var cat = node.cat;
		var icon = target.parameters.iconPath + "ordner.gif";
		var ph = "";
//		alert(target.parameters.iconPath);
		if (node.children.length == 0) {
			if (node.isLastChild())
				icon = target.parameters.iconPath + "lastchild.gif";
			else
				icon = target.parameters.iconPath + "child.gif";
		} else if (node.parent != null) {
			if (node.isLastChild())
				ph = "<img align='middle' src='" + target.parameters.iconPath + "lastchild.gif'>";
			else
				ph = "<img align='middle' src='" + target.parameters.iconPath + "child.gif'>";
		}
		// insert placeholders depending on the node's level
		var parent = node;
		for (var i = node.level - 1; i > 0; i--) {
			parent = parent.parent;
			if (parent.isLastChild()) {
				ph = "<img align='middle' src='" + target.parameters.iconPath + "platzhalter.gif'>" + ph;
			} else {
				ph = "<img align='middle' src='" + target.parameters.iconPath + "line.gif'>" + ph;
			}
		}
		var result = true;
		// one displayed column?
		if (target.parameters.oneColumn) {
			if (node.children.length > 0) {
				icon = target.parameters.iconPath + "ordner.gif";
				var ih = "<span class='suggGroupCaption'><nobr>" + ph + "<img align='middle' src='" + icon + "'>" +
							replaceHTMLEntities(rowArray[row][0]) + 
							"&nbsp;&nbsp;</nobr></span>";
				// determine whether events on these rows
				result = (target.parameters.flags & AS_GENERATED_CATEGORIES_NOT_SELECTABLE) != AS_GENERATED_CATEGORIES_NOT_SELECTABLE;
			} else {
				var ih = "<span class='suggGroupProductOnly'><nobr>" + ph + "<img align='middle' src='" + icon + "'>" +
							replaceHTMLEntities(rowArray[row][0]) + 
							"&nbsp;&nbsp;</nobr></span>";
			}
		} else {
			// two displayed columns
			if (node.children.length > 0) {
				icon = target.parameters.iconPath + "ordner.gif";
				var ih = "<span class='suggGroupCaption'><nobr>" + ph + "<img align='middle' src='" + icon + "'>" +
							replaceHTMLEntities(rowArray[row][0]) + 
							"&nbsp;&nbsp;</nobr></span><span class='suggGroupCat'><nobr>" +
							replaceHTMLEntities(cat) +
							"&nbsp;&nbsp;</nobr></span>";
				// determine whether events on these rows
				result = (target.parameters.flags & AS_GENERATED_CATEGORIES_NOT_SELECTABLE) != AS_GENERATED_CATEGORIES_NOT_SELECTABLE;
			} else {
				var ih = "<span class='suggGroupProduct'><nobr>" + ph + "<img align='middle' src='" + icon + "'>" +
							replaceHTMLEntities(rowArray[row][0]) + 
							"&nbsp;&nbsp;</nobr></span><span class='suggGroupCat'><nobr>" +
							replaceHTMLEntities(cat) +
							"&nbsp;&nbsp;</nobr></span>";
			}
		}
	 	iDiv.innerHTML = ih;
	 	return result;
	} catch (E) {
		if (target.parameters.debug)
			alert("mmGroupedRowFunction error: " + E);
	}
}

function mmGroupedOnActivate(input, row) {
	var target = mm_inputs[input.mm_refcnt];
	var node = row[2];
	var realRow = node.row;
	if ((typeof target.parameters.oldOnActivate != "undefined") && (target.parameters.oldOnActivate != null) && (target.parameters.oldOnActivate != "")) {
		// generated node?
		if (realRow == null) {
			// build realRow on the fly
			realRow = new Array(node.value);
			realRow[input.fieldnames[0]] = node.value;
			// append enough columns to make it look like an original row
			// generate row index aliases
			for (var i = 1; i < input.fieldnames.length; i++) {
				realRow.push("");
				realRow[input.fieldnames[i]] = "";
			}
		}
		if (target.parameters.oldOnActivate(target, realRow))
			mmSubmitString(target, realRow[target.parameters.valueField]);
	} else {
		// standard behaviour
		var value = node.value;
		if (node.children.length > 0) {
			input.value = value;
			setTimeout(function() {
				input.focus();
				input.suggest();
			}, 50);
		} else {
			mmSubmitString(target, realRow[target.parameters.valueField]);
		}
	}
	// don't submit
	return false;
}
