var navBuilderConstructor=navBuilder.prototype.constructor;
navBuilder=function(string)
{
	navBuilderConstructor.call(this,string);
	this.window=window;
}

function Nodes(navBuilder,baseDiv)
{
	this.navBuilder=navBuilder;
	this.addNodes;
	this.removeNodes;
	this.repaintNodes;
	this.openNodes=new Array();
	this.baseDiv=baseDiv;
	
	this.reset=function()
	{
		this.addNodes=new Map();
		this.removeNodes=new Array();
		this.repaintNodes=new Array();
	}
	
	this.reset();
}

/* BEGIN CORE DEFINITIONS */
Nodes.prototype.toggleNodeDisplay=function(nodeId, collectionService, frameName)
{
	var win=this.getWindow();
	var doc = win.document;
	if (frameName != null && frameName != "")
	{
		var frame = win.frames[frameName];
		if (typeof(frame) != "undefined")
		{
			doc = win.frames[frameName].document;
		}
	}

	/* Declare variables containing the two images that need to be swapped
		ASSUMPTION: The first (and usually only) two children of the linkObject
		container will be the tree connector and the collection/folder icon
		respectively. */
	var linkObject = doc.getElementById(nodeId + "_link");
	var treeConnectorImage = linkObject.childNodes[0];
	var treeIconImage = linkObject.childNodes[1];
	var divContainer = doc.getElementById(nodeId);

	/* Toggle the display status of the associated DIV container accordingly. */
	if (treeConnectorImage.src.indexOf("closed.gif") > -1)
	{
		/* The collection service is used to dynamically generate and insert
		   child nodes for collections in the Library (index) sub-tree (for
		   nodes that don't have a collection service, their child nodes were
		   generated at the time the page is initially loaded). */

		/* Run the collection service routines only if the child nodes haven't
		   been loaded already (e.g. the <div> container doesn't already contain
		   any <table> code). */
		if (collectionService && divContainer.getElementsByTagName("table").length == 0)
		{
			/* This conditional was added to allow use with Javascript-based
			   collection services.  This is included to enable a broaded range
			   of customization; it isn't currently used in the standard
			   implementation. */
			if (collectionService.indexOf("javascript:") == 0)
			{
				jsLoadFunction = collectionService.split(":")[1];
				eval(jsLoadFunction);
			}
			else
			{
				/* Load hidden frame with lm_dir_page.htm template. The onload
				   event of this page calls the parseChildNodesXml() function.
				   This can potentially be used with other services for
				   different customizations.*/
				top.hiddenActionWindow.location.replace(collectionService);
			}
			/* Note: the code that displays the container should be in the
			   collection service functions.*/
		}
		else
		{
			if (divContainer!=null && divContainer.hasChildNodes())
			{
				// Display existing child nodes.
				divContainer.style.display = "block"; 
			}
		}
		// swap to the 'open' icon
		treeConnectorImage.src = treeConnectorImage.src.replace(/closed\.gif/, "open.gif");
		treeIconImage.src = treeIconImage.src.replace(/closed\.gif/, "open.gif");
	}
	else
	{
		// Hide child nodes, swap the graphic to 'closed'
		divContainer.style.display = "none";
		treeConnectorImage.src = treeConnectorImage.src.replace(/open\.gif/, "closed.gif");
		treeIconImage.src = treeIconImage.src.replace(/open\.gif/, "closed.gif");
	}
}

Nodes.prototype.toggleTrayDisplay=function(nodeId)
{
	var win=this.getWindow();
	var context=win.top;

	var trayContainer = win.document.getElementById(nodeId);
	var trayBuffer = win.document.getElementById("trayA_buffer");
	var parentOb = trayContainer;
	var trayScrollBox, trayCell;

	while (parentOb.id != "trayTable")
	{
		if (parentOb.id.indexOf("scrollBox") != -1) { trayScrollBox = parentOb; }
		else if (parentOb.id.indexOf("cell") != -1) { trayCell = parentOb; }
		parentOb = parentOb.parentNode;
	}
	
	var trayId = trayScrollBox.id.split("_")[1];
	var trayHeader = win.document.getElementById("trayA_" + trayId + "_header");
	var trayHeaderLink = trayHeader.getElementsByTagName("A")[0];
	var trayArrowImage = trayHeader.getElementsByTagName("IMG")[0];
	if (trayCell.className == "trayA_cell_closed")
	{
		if (nodeId == context.openTrayId)
		{
			// We have gotten into a bad state, probably through a refresh of the navigation pane,
			// where we are trying to close a tray which is already closed.  Fix the javascript
			// variables and return.
			
			context.openTrayCount--;
			if (allowMultipleTrays == false)
			{
				context.openTrayId = "";
			}
			return;
		}
	
		// close currently open tray, if any
		if (allowMultipleTrays == false)
		{
			if (context.openTrayId != "")
			{
				this.toggleTrayDisplay(context.openTrayId);
			}
			context.openTrayId = nodeId;
		}
		
		// Safari workaround: set the size of the new tray to the size of the current open space
		var trayBufferDims = new top.dimensionFinder(trayBuffer);
		var trayScrollBoxHeight = parseInt(trayBufferDims.height);
		trayScrollBox.style.height = trayScrollBoxHeight + "px";

		trayScrollBox.style.display = "block";
		trayCell.className = "trayA_cell_open";
		trayHeaderLink.className = "trayA_headerLink_open";
		trayArrowImage.src = trayA_ArrowDown;
		context.openTrayCount++;

		/* Declare variables used to reference XML node in order to get attribute values. */
		var xmlNode = this.navBuilder.getNodeById(nodeId);

		/* Declare variable used to determine value (and/or existence) of collection service. In this
			implementation, collection service is used to dynamically generate and insert child nodes
			for collections in the Library (index) sub-tree (for nodes that don't have a collection
			service, their child nodes were generated at the time the page is initially loaded). */
		var collectionService = xmlNode.getAttribute("collection_service");

		/* Declare variable to determine value (and/or existence) of tray_doc attribute. In cases where
			a tray contains an IFrame used to load a separate document (such as the Search tray), the
			tray_doc attribute provides the URL of the document to be loaded when the tray is opened. */
		var trayDoc = xmlNode.getAttribute("tray_doc");

		if (collectionService && trayContainer.getElementsByTagName("table").length == 0)
		/* Run the collection service routines only if the child nodes haven't been loaded already
			(e.g. the <div> container doesn't already contain any <table> code). */
		{
			if (collectionService.indexOf("javascript:") == 0)
			/* This conditional was added to allow use with Javascript-based collection services.
				This is included to enable a broader range of customization; it isn't currently used
				in this implementation. */
			{
				jsLoadFunction = collectionService.split(":")[1];
				eval(jsLoadFunction);
			}
			else
			{
				/* Load hidden frame with lm_dir_page.htm template. The onload event of this page calls the
				parseChildNodesXml() function. This can potentially be used with other services for different
				customizations.*/
				hiddenActionWindow.location.replace(collectionService);
			}
			/* Note: the code that displays the container is located in the collection service-related functions.*/
		}

		else if (xmlNode.getAttribute("tray_doc"))
		/* If the current node has a tray_doc attribute, load that URL into the corresponding iframe for that
			node (if the frame hasn't been loaded already).  */
		{
			var trayIframe = win.document.getElementById(trayContainer.id + "_iframe");
			if (trayIframe.src == null || trayIframe.src == "" || trayIframe.src == blankPageUrl ||
			    typeof(trayIframe.contentDocument) == "undefined" ||
			    typeof(trayIframe.contentDocument.body) == "undefined" ||
			    typeof(trayIframe.contentDocument.body.innerHTML) == "undefined" ||
			    trayIframe.contentDocument.body.innerHTML.length == 0)
			{
				trayIframe.src = xmlNode.getAttribute("tray_doc");
			}
		}
	}

	else
	{
		trayScrollBox.style.display = "none";
		trayScrollBox.style.height = "1px";
		trayCell.className = "trayA_cell_closed";
		trayHeaderLink.className = "trayA_headerLink_closed";
		trayArrowImage.src = trayA_ArrowRight;
		context.openTrayCount--;

		if (allowMultipleTrays == false)
		{
			context.openTrayId = "";
		}
	}

	if (context.openTrayCount == 0) trayBuffer.style.height = "auto";
	else trayBuffer.style.height = "1px";

	if (its.mozilla || its.nn || its.safari)
	/* Display adjustment for early versions of NN7/Moz1*/
	{
		dynamicTrayAdjustInit();
	}
}
/* END CORE DEFINITIONS */

Nodes.prototype.getWindow=function()
{
	if (this.navBuilder.window.leftNavWindow)
	{
		return(this.navBuilder.window.leftNavWindow);
	}
	else
	{
		return(this.navBuilder.window);
	}
}

Nodes.prototype.getDocument=function()
{
	return(this.getWindow().document);
}

Nodes.prototype.removeNode=function(nodeId)
{
	var node = this.getNode(nodeId);
	if (node != null)
	{
		this.removeNodeObject(node);
	}
/*	else
	{
		if (this.navBuilder.xmlNodeMap[nodeId]!=null)
		{
			alert("node not found for "+nodeId);
			delete this.navBuilder.xmlNodeMap[nodeId];
		}
	}*/
}
Nodes.prototype.removeNodeObject=function(node)
{
	//Recursively remove nodes
	var nodeId=node.getAttribute("id");
	while (node.childNodes.length > 0)
	{
		var child=node.childNodes[0];
		this.removeNodeObject(child);
	}
	var parentNode=node.parentNode;
	if (parentNode!=null)
	{
		var parentId = parentNode.getAttribute("id");
		this.repaintNodes[parentId]=true;
		var before=parentNode.childNodes.length;
		parentNode.removeChild(node);
	}

	delete this.navBuilder.xmlNodeMap[nodeId];
}

Nodes.prototype.deleteNodeHtml=function(nodeId)
{
	var node = this.navBuilder.getNodeById(nodeId);
	if (node == null)
	{
		return;
	}
	
	var nodeLocation = this.navBuilder.xmlNodeMap[nodeId].location;
	var parentId = node.parentNode.getAttribute("id");
	var childDivContainer = this.getDocument().getElementById(nodeId);
	var childLinkContainer = this.getDocument().getElementById(nodeLocation);

	if (childDivContainer!=null)
	{
		childDivContainer.parentNode.removeChild(childDivContainer);
	}
	if (childLinkContainer!=null)
	{
		childLinkContainer.parentNode.removeChild(childLinkContainer);
	}
}


Nodes.prototype.draw=function(nodeId,nodeData)
{
	var node=this.getNode(nodeId);
	if (node!=null)
	{
		mapXMLTree(node, this.navBuilder.xmlNodeMap);
/*for (var nodeId2 in this.removeNodes)
{
	if (this.removeNodes[nodeId2]!=null)
	{
		if (this.getNode(nodeId2)!=null || this.navBuilder.xmlNodeMap[nodeId2]!=null)
		{
		throw "******** node not removed... "+nodeId2+" "+nodeId;
		}
	}
}*/

		var node=this.getNode(nodeId);
		var element=this.getElement(nodeId);
		if (element!=null)
		{
			//Remove all children elements
			while (element.childNodes.length > 0)
			{
				element.removeChild(element.childNodes[0]);
			}
			generateChildNodeDisplayCode(this.navBuilder, node, element);
			element.style.display = "block";
/*var childId=nodeData['id'];
if (this.getDocument().getElementById(childId)==null)
{
	var children=new Array();
	for (var i=0;i < node.childNodes.length; i++)
	{
		children[children.length]=node.childNodes[i].getAttribute("id");
	}
	alert("not found "+nodeId+" "+childId+" ["+children.join(",")+"] "+nodeData);
}*/
		}
	}
}

Nodes.prototype.commit=function()
{
	var addNodesKeys=this.addNodes.getKeys();
	for (var i=0;i < addNodesKeys.length; i++)
	{
		var nodeId=addNodesKeys[i];
		var objs=this.addNodes.get(nodeId);
		/*
		 * Now before we actually add it we need to make sure that this node isn't its own parent
		 * If it is we should just ignore it
		 */

		var nodeData=objs[1];
		var parentId=nodeData['parentId'];

		for (var node=this.navBuilder.getNodeById(parentId); node!=null && typeof(node.getAttribute)!="undefined"; node=node.parentNode)
		{
			if (node.getAttribute('id')==nodeData['id'])
			{
				delete this.addNodes[nodeId];
			}
		}
	}
	//Remove all of the node html first because deleting nodes alters the location
	for (var nodeId in this.removeNodes)
	{
		if (this.removeNodes[nodeId]!=null)
		{
			this.deleteNodeHtml(nodeId);
		}
	}
	for (var i=0;i < addNodesKeys.length; i++)
	{
		var nodeId=addNodesKeys[i];
		this.deleteNodeHtml(nodeId);
	}
	
//this.verifySync();
	var nodeObjects=new Array();
	for (var nodeId in this.removeNodes)
	{
		if (this.removeNodes[nodeId]!=null)
		{
			nodeObjects[nodeObjects.length]=this.navBuilder.getNodeById(nodeId);
		}
	}

	for (var i=0;i < addNodesKeys.length; i++)
	{
		var nodeId=addNodesKeys[i];
		nodeObjects[nodeObjects.length]=this.navBuilder.getNodeById(nodeId);
		var nodeData=this.addNodes.get(nodeId)[1];
		var parentId=nodeData['parentId'];
		if (this.addNodes.get(parentId)==null && (this.removeNodes[parentId]!=null || this.navBuilder.getNodeById(parentId)==null))
		{
			throw "parent node does not exist "+parentId+" "+nodeId;
		}
	}
	
	for (var i=0;i < nodeObjects.length; i++)
	{
		if (nodeObjects[i]!=null)
		{
			this.removeNodeObject(nodeObjects[i]);
		}
	}
	
	for (var i=0;i < addNodesKeys.length; i++)
	{
		var nodeId=addNodesKeys[i];
		var objs=this.addNodes.get(nodeId);
		
		var nodeData=objs[1];
		var type=objs[0];

		this.removeNode(nodeId);

		var parentId=nodeData['parentId'];

		var pass=new Array();
		var params=new Array();

		for (var name in nodeData)
		{
			if (nodeData[name])
			{
				pass[pass.length]="params["+params.length+"]";
				params[params.length]=name+"=="+nodeData[name];
			}
		}
//alert("parent '"+nodeData['parentId']+"' '"+nodeData['id']+"'");
/*if (this.navBuilder.getNodeById(nodeData['parentId'])==null)
{
throw "error: parent does not exist "+nodeData['parentId']+" "+nodeData['id']+" "+typeof(this.addNodes.get(nodeData['parentId']))+" '"+this.addNodes.getKeys()+"' '"+this.removeNodes+"'";
}*/
//alert("adding '"+nodeData['id']+"'");
		eval("this.navBuilder.addChildNodeTo(parentId,type,"+pass.join(",")+")");
/*if (this.navBuilder.getNodeById(nodeId)==null)
{
throw "error: node does not exist "+nodeId;
}*/

		this.repaintNodes[parentId]=nodeData;
	}
	for (var nodeId in this.repaintNodes)
	{
		this.draw(nodeId,this.repaintNodes[parentId]);
	}
	for (var i=0;i < addNodesKeys.length; i++)
	{
		var nodeId=addNodesKeys[i];
		var objs=this.addNodes.get(nodeId);
		
		var nodeData=objs[1];
		if (nodeData["isExpanded"])
		{
			this.open(nodeData["id"]);
		}
	}
	
/*for (var nodeId in this.addNodes)
{
	if (this.addNodes[nodeId]!=null)
	{
		var nodeData=this.addNodes[nodeId][1];
		if (this.navBuilder.getNodeById(nodeData['id'])==null)
		{
			alert("Not actually added! "+nodeData['id']);
		}
	}
}*/

	this.reset();

	if (this.navBuilder.activeId)
	{
		if (this.navBuilder.activeIdCommit && (this.navBuilder.activeId != this.navBuilder.activeIdCommit))
		{
			var div=this.getDocument().getElementById(this.navBuilder.activeIdCommit+"_label");
			if (div != null)
			{
				div.style.borderWidth="";
				div.style.borderStyle="";
				div.style.borderColor="";
			}
		}
		this.navBuilder.activeIdCommit=this.navBuilder.activeId;
		var div=this.getDocument().getElementById(this.navBuilder.activeIdCommit+"_label");
		if (div != null)
		{
			div.style.borderWidth="1";
			div.style.borderStyle="dotted";
			div.style.borderColor="Highlight";
		}
	}
}

function size(obj)
{
	var count=0;
	for (name in obj)
	{
		count++;
	}
	return(count);
}

Nodes.prototype.add=function(parentXML,type)
{
	if (parentXML==null)
	{
		parentXML='NAVTREE';
	}
	var params=new Array();
	var url;
	for (var i=2; i < arguments.length; i=i+2)
	{
		var name=arguments[i];
		var value=arguments[i+1];
		if (name=="onclick")
		{
			name="url";
			value='#" onclick="'+value+';return(false);';
		}
		params[name]=value;
	}
	params['label']="<span id='"+params['id']+"_label'>"+params['label']+"</span>";
	params['parentId']=parentXML;
	
	//Check to see if the parent exists
	if (this.getNode(parentXML)==null)
	{
		//Are we adding
		if (this.addNodes.get(parentXML)==null)
		{
			throw "error: parent '"+parentXML+"' does not exist";
		}
	}
	else
	{
		//Was it removed
		var parentNode=this.getNode(parentXML);
		while(parentNode!=null && typeof(parentNode.getAttribute)!="undefined")
		{
			var id=parentNode.getAttribute('id');
			if (this.removeNodes[id]!=null)
			{
				throw "error: parent '"+id+"' being removed";
			}
			parentNode=parentNode.parentNode;
		}
	}

	if (this.addNodes.get(params['id'])!=null)
	{
		return;
		//("replacing... "+params['id']);
	}
	this.addNodes.put(params['id'],[type,params]);
	
	delete this.removeNodes[params['id']];
}

Nodes.prototype.removeChildren=function(nodeId)
{
	var node=this.getNode(nodeId);
	if (node!=null)
	{
		for (var i=0;i < node.childNodes.length; i++)
		{
			var child=node.childNodes[i];
			this.remove(child.getAttribute("id"));
		}
	}
}

Nodes.prototype.remove=function(nodeId)
{
	this.removeNodes[nodeId]=true;
	this.addNodes.remove(nodeId);
}

Nodes.prototype.verifyNotExist=function(nodeId)
{
	this.verifyNotExistNode(this.navBuilder.xmlRoot,nodeId,"");
}

Nodes.prototype.verifyNotExistNode=function(node,nodeId,location)
{
	var id=node.getAttribute("id");
	if (id==nodeId)
	{
		throw nodeId+" exists '"+node.parentNode+"' "+location+" "+this.navBuilder.xmlNodeMap[nodeId].location;
	}
	for (var i=0;i < node.childNodes.length; i++)
	{
		try
		{
			this.verifyNotExistNode(node.childNodes[i],nodeId,location+"."+i);
		}
		catch(e)
		{
			throw id+","+e
		}
	}
}

Nodes.prototype.verifySync=function()
{
	this.verifySyncNode(this.navBuilder.xmlRoot,"");
}

Nodes.prototype.verifySyncNode=function(node,location)
{
	var id=node.getAttribute("id");
	var nodePointer=this.navBuilder.xmlNodeMap[id];
//alert(nodePointer+" "+id+" "+node);
	if (nodePointer!=null && location!=".2")
	{
//alert(location+" ."+nodePointer.location);
		if (location!=("."+nodePointer.location))
		{
			throw "Not synced "+id+" "+location+" ."+this.navBuilder.xmlNodeMap[id].location;
		}
	}
	for (var i=0;i < node.childNodes.length; i++)
	{
		if (node.childNodes[i].parentNode!=node)
		{
			throw "parent node out of sync";
		}
		this.verifySyncNode(node.childNodes[i],location+"."+i);
	}
}

Nodes.prototype.getNodeAncestoryAttribute=function(nodeId,attribute)
{
	var node=this.getNode(nodeId);
	var array=new Array();
	for(var i=0; node!=null; i++)
	{
		if (node!=null)
		{
			if (typeof(node.getAttribute)!="undefined")
			{
				var value=node.getAttribute(attribute);
				if (value!=null)
				{
					array[array.length]=value;
				}
			}
		}
		node=node.parentNode;
		/*var parentId=node.getAttribute("parentId");
		{
			node=this.getNode(parentId);
		}*/
	}

	return(array);

}

Nodes.prototype.toggleNode=function(nodeId,bService)
{
	var node=this.getNode(nodeId);
	if (node!=null)
	{
		var nodeId=node.getAttribute("id");

		var linkObject = this.getDocument().getElementById(nodeId + "_link");

		if (linkObject != null)
		{
			if (bService)
			{
				var collectionService=node.getAttribute("collection_service");
				this.toggleNodeDisplay(nodeId,collectionService);
			}
			else
			{
				this.toggleNodeDisplay(nodeId,collectionService);
			}
		}
	}
}

Nodes.prototype.isNode=function(nodeId)
{
	var node=this.getNode(nodeId);
	if (node!=null)
	{
		var nodeId=node.getAttribute("id");
		var element = this.getDocument().getElementById(nodeId);

		if (typeof(node.parentNode.getAttribute)!="undefined")
		{
			if (node.parentNode.getAttribute("id")=="NAVTREE")
			{
				return(true);
			}
		}
		if (element != null)
		{
			return(element.parentNode.id.substring(0,4)!="tray");
		}
	}
	return(true);
}

Nodes.prototype.open=function(nodeId)
{
	if (this.isNode(nodeId))
	{
		this.openNode(nodeId);
	}
	else
	{
		this.openTray(nodeId);
	}
}

Nodes.prototype.openTray=function(nodeId)
{
	var node=this.getNode(nodeId);
	if (node != null)
	{
		var nodeId=node.getAttribute("id");
		var trayContainer = this.getDocument().getElementById(nodeId);
		var parentOb = trayContainer;
		var trayCell;

		while (parentOb.id != null && parentOb.id != "trayTable")
		{
			if (parentOb.id.indexOf("cell") != -1)
			{
				trayCell = parentOb;
			}
			parentOb = parentOb.parentNode;
		}

		if (trayCell != null && trayCell.className == "trayA_cell_closed")
		{
			this.toggleTrayDisplay(nodeId);
		}
	}
}

Nodes.prototype.isNodeClosed=function(nodeId)
{
	var element=this.getDocument().getElementById(nodeId+"_link");
	if (element)
	{
		var child=element.childNodes[0];
		var src=child.src;
		if (src.substring(src.length-8)=="open.gif")
		{
			return(false);
		}
	}
	return(true);
}

Nodes.prototype.openNode=function(nodeId,bService,count,opened)
{
	var element=this.getDocument().getElementById(nodeId+"_link");
	var node=this.getNode(nodeId);
	if (element==null || node==null)
	{
		if (count==null || opened!=this.opened)
		{
			count=0;
		}
		if (count < 100)
		{
			utils.objectTimeout(this,this.openNode,nodeId,bService,count+1,this.opened);
		}
		else
		{
			//alert("unable to open "+nodeId);
		}
	}
	else if (this.isNodeClosed(nodeId))
	{
		if (!this.opened)
		{
			this.opened=0;
		}
		else
		{
			this.opened++;
		}
		this.toggleNode(nodeId,bService);
	}
}

Nodes.prototype.closeNode=function(nodeId)
{
	if (!this.isNodeClosed(nodeId))
	{
		this.toggleNode(nodeId);
	}
}

Nodes.prototype.addNode=function(parentXML,type)
{
	if (parentXML==null)
	{
		parentXML='NAVTREE';
	}
	var params="";
	var url;
	for (var i=3; i < addNode.arguments.length; i++)
	{
		var argument=",addNode.arguments["+i+"]";
		var pair=addNode.arguments[i].split("==");
		//Clicking on anchors in modal windows bring up other windows
		//This prevents it
		if (pair[0]=="url" && pair[1].length > 11)
		{
			if (pair[1].substring(0,11)=="javascript:")
			{
				url='url==#" onclick="'+pair[1]+';return(false);';
				argument=",url";
			}
		}
		params+=argument;
	}
	params+=",'parentId=="+parentXML+"'";

	eval("this.navBuilder.addChildNodeTo(parentXML,type"+params+")");

	//mapXMLTree(this.navBuilder.xmlRoot, this.navBuilder.xmlNodeMap);
}

Nodes.prototype.getNode=function(nodeId)
{
	return(this.navBuilder.getNodeById(nodeId));
}

Nodes.prototype.hasNode=function(nodeId)
{
	if (this.removeNodes[nodeId]!=null)
	{
		return(false);
	}
	if (this.addNodes.get(nodeId)!=null)
	{
		return(true);
	}
	return(this.navBuilder.getNodeById(nodeId)!=null);
}

/*Nodes.prototype.removeNode=function(nodeId)
{
	if (this.navBuilder.xmlNodeMap[nodeId])
	{
		var curPathIndex = this.navBuilder.xmlNodeMap[nodeId].location;
		var curNode = this.getNode(nodeId);
		if (curNode != null)
		{
			var parentId = curNode.parentNode.getAttribute("id");
			var curHtmlContainer = this.getDocument().getElementById(nodeId);
			var curLinkContainer = this.getDocument().getElementById(curPathIndex);
			var parentHtmlContainer = this.getDocument().getElementById(parentId);

			if (parentHtmlContainer != null)
			{
				if (curHtmlContainer != null)
				   parentHtmlContainer.removeChild(curHtmlContainer);
				if (curLinkContainer != null)
				   parentHtmlContainer.removeChild(curLinkContainer);
			}
			this.navBuilder.deleteItem(nodeId);
		}
	}
}*/

Nodes.prototype.show=function(parentXML,parentHTML)
{
	mapXMLTree(this.navBuilder.xmlRoot, this.navBuilder.xmlNodeMap);

	var parentNode;
	if (parentXML==null || parentXML=="NAVTREE")
	{
		parentNode = this.navBuilder.xmlRoot;
	}
	else
	{
		parentNode = this.navBuilder.getNodeById(parentXML);
	}

	if (parentHTML==null)
	{
		parentHTML=parentNode.getAttribute("id");
	}

	var parentHtmlContainer=this.getElement(parentHTML);

	if (parentHtmlContainer)
	{
		generateChildNodeDisplayCode(this.navBuilder, parentNode, parentHtmlContainer);
		parentHtmlContainer.style.display = "block";
	}
}

Nodes.prototype.setActive=function(nodeId)
{
	this.navBuilder.activeId=nodeId;
}

Nodes.prototype.hasChild=function(parentId,nodeId)
{
	var node=this.getNode(parentId);
	if (node != null)
	{
		for (var i=0;i < node.childNodes.length; i++)
		{
			if (node.childNodes[i].getAttribute("id")==nodeId)
			{
				return(true);
			}
		}
	}
	return(false);
}

Nodes.prototype.hasAncestor=function(nodeId,ancestorId)
{
	var node=this.getNode(nodeId);
	return(this.hasAncestorNode(node,ancestorId));
}
Nodes.prototype.hasAncestorNode=function(node,ancestorId)
{
	if (node!=null)
	{
		if (typeof(node.getAttribute)=="function" && node.getAttribute("id")==ancestorId)
		{
			return(true);
		}
		var parentNode=node.parentNode;
		if (parentNode!=null)
		{
			return(this.hasAncestorNode(parentNode,ancestorId));
		}
	}
	return(false);
}

Nodes.prototype.setNodeLabel=function(nodeId,label)
{
	var node=this.getNode(nodeId);
	if (node!=null)
	{
		node.setAttribute("label",label);
	}
	var element=this.getDocument().getElementById(nodeId+"_label");
	if (element!=null)
	{
		element.innerHTML=label;
	}
}

Nodes.prototype.getElement=function(nodeId)
{
	if (nodeId=="NAVTREE" && this.baseDiv!=null)
	{
		return(this.getDocument().getElementById(this.baseDiv));
	}
	return(this.getDocument().getElementById(nodeId));
}

function NodeUtils()
{
}

NodeUtils.prototype.getNodes=function(navBuilder,baseDiv)
{
	if (navBuilder!=null)
	{
		if (navBuilder.nodes!=null)
		{
			return(navBuilder.nodes);
		}
		else
		{
			navBuilder.nodes=new Nodes(navBuilder,baseDiv);
			return(navBuilder.nodes);
		}
	}
}

NodeUtils.prototype.commit=function()
{
	alert("Deprecated!");
}

var nodeUtils=new NodeUtils();
