        var ajaxRequest = null;
		var ajaxSessionRequest = null;
        var ajaxRequestURL = "/TradePoint/Ajax/ItemMenu?actionType=loadNodes";
		var urlChangeSession = "/TradePoint/Ajax/ChangeSessionTree";
        var count = 0;
        var tree_categoriesToExpand = new Array();
        var tree_selectedCategoryNo = 0;
        var tree_selectedId;
        var tree_activeCatalogNo = "";
        var leaveNodesOpen = true;            // set this to true if you only want one node at a time to be opene
		var tree_nodeIsSelected   = 0;
		var reqCNo = -1;
		var tree_removeFirstId = -1;
        
    /*    =========================================================
        leafClick()
        Triggered when a leaf in the tree is clicked.
        Expands and collapses a branch.
        Calls the server via Ajax to load the sub nodes. If they already are
        loaded they will be displayed and no server request made.
        =========================================================  */
        function leafClick(categoryHrefEl, categoryNo, className, forceOpen,reguestCategoryNo)
        {
            // get the parent element (LI)
			var li = null;
            if(!categoryNo && categoryNo != 0)
            {
                if(categoryHrefEl)
				{
					if(categoryHrefEl.id.indexOf('cat_')!=-1)
						li = categoryHrefEl;
					else
						li = categoryHrefEl.parentNode;			
                    categoryNo = String(li.id).substr(4);
				}
				
            }
            else
            {
                var li = document.getElementById('cat_'+categoryNo);	
            }
            
            if(!li)
			{
				//alert('failed to locate ('+categoryNo+')')
                return;
			}
            // close open root nodes. This will only occur if a rot node is clicked, otherwise we might close our own parent node...
            if(!leaveNodesOpen && li.parentElement.className == 'tm_tree')
            {
                // get the siblings
                var nodes = li.parentElement.childNodes;
                for(var n=0; n<nodes.length; n++)
                {
                    if(nodes[n].className.indexOf('tm_opened') != -1)
                        nodes[n].className = nodes[n].className.replace('tm_opened', 'tm_closed');
                }
            }
            
            tree_checkSibilings(categoryNo,reguestCategoryNo);
			// no sub cats means do not expand
            if(li.className.indexOf('tm_bullet')!= -1)
			{
                tree_refreshSelectedNode();
				return;
            }
            // check if the node has been expanded
            if(li.className.indexOf('tm_opened')!= -1 && !forceOpen)
            {
                // update the LI
                li.className = 'tm_closed';
                
                // possibly expand another node
                tree_expandNextInQueue();
                
                // possibly update the selected node
                tree_refreshSelectedNode();
				
				tree_hiddenSubtreeNodes(categoryNo);
                return;
            }
            
            // if the subnodes are collapsed, they might still be loaded
            if(li.getAttribute('loaded') == 'yes')
            {
                // get the sub nodes container
                li.className = 'tm_opened';
                
                // possibly expand another node
                tree_expandNextInQueue();
                
                // possibly update the selected node
                tree_refreshSelectedNode();
				
				var urlCS = urlChangeSession + "?categoryNoAdd=" + categoryNo +"&rdParam=" +Math.random()*10000;
				tree_sendAjaxRequest(urlCS );
				
                return;
            }
			
            // Possibly add an UL with temporary content
            var placeHolder = '<li><img src="/systemimages/pieSlicesSmall.gif" /></li>';
            var ul = document.getElementById('branch_'+categoryNo);
            if(ul)
                ul.innerHTML = placeHolder;
            else
                li.innerHTML += '<ul id="branch_'+categoryNo+'" class="'+className+'">'+placeHolder+'</ul>';
            
            // Send the AJAX request
			reqCNo = reguestCategoryNo;
			
				
			var url = ajaxRequestURL + "&parentCategoryNo=" + categoryNo + "&tree_nodeIsSelected=" + tree_nodeIsSelected+"&reguestCategoryNo="+reqCNo;
            ajaxRequest = Ajax.getTransport();
            if( ajaxRequest )
            {   
                ajaxRequest.open( "GET", url, true );
                ajaxRequest.onreadystatechange = expandTreeBranch;
                ajaxRequest.send( "" );
            }
            else
                alert('No AJAX transport found!');
        }
        
    /*    =========================================================
        expandTreeBranch()
        Triggered when an Ajax tree request returns.
        replaces the temporary placeholder with a UL listing of tree nodes.
        =========================================================  */
        function expandTreeBranch()
        {
            // only if ajaxRequest shows "loaded"
            if( ajaxRequest.readyState == 4 )
            { 
            
                // only if "OK"
                if( ajaxRequest.status == 200 )
                {
                    // get the returned result
                    var LINodes = ajaxRequest.responseText;
                    
                    // extract the id of the UL to populate
                    var separator = LINodes.indexOf('$');       
                    var parentCategoryNo = LINodes.substr(0,separator);
                    
                    // populate the UL with LI nodes
                    var UL = document.getElementById('branch_'+parentCategoryNo);
                    UL.innerHTML = LINodes.substr(separator+1);
                    
                    // update the parent node (LI)
                    var parentNode = document.getElementById('cat_'+parentCategoryNo);
                    parentNode.setAttribute('loaded', 'yes');
                    parentNode.className = 'tm_opened';
					
					var linkNode = document.getElementById('link_'+parentCategoryNo);
					if(linkNode)
						linkNode.className = parentNode.className;
                    
                    // possibly expand another node
					tree_expandNextInQueue();
                    
                    // possibly update the selected node
                    tree_refreshSelectedNode();
                }
                else
                {
                    showAjaxError(ajaxRequest);
                    okToGo = false;
                }
            }
        }
        
    /*    =========================================================
        tree_setSelectedNode()
        stores the category number which should be marked as selected
        =========================================================  */
        function tree_setSelectedNode(categoryNo)
        {
            tree_selectedCategoryNo = categoryNo;
        }
        
    /*    =========================================================
        tree_setActiveCatalogNo()
        if the passed catalog number differs from the active catalog number
        the tree will be cleansed
        =========================================================  */
        function tree_setActiveCatalogNo(catalogNo)
        {
            if(tree_activeCatalogNo != catalogNo)
            {
				//alert('Changed from catalog ('+tree_activeCatalogNo+') to ('+catalogNo+')')
                tree_activeCatalogNo = catalogNo;
                //document.getElementById('cat_0').innerHTML = "";
                
                // reload the root categories
                //leafClick(null, 0, 'tm_tree', false);
            }
        }
    		
    /*    =========================================================
	tree_setSelectedNode()
          stores the category number which should be marked as selected
         =========================================================  */
        function tree_setSelectedVal(selVal)
        {
            tree_nodeIsSelected = selVal;
        }
        
      
    /*    =========================================================
        tree_selectNode()
        verifies and updates the class names of the selected node to ensure
        the right node is marked as selected
        =========================================================  */
        function tree_refreshSelectedNode()
        {
            var selectedLI = document.getElementById(tree_selectedId);
            
            if(!selectedLI && (tree_selectedCategoryNo || tree_selectedCategoryNo!=0))
                selectedLI = document.getElementById('cat_'+tree_selectedCategoryNo);
            
            if(!selectedLI)
                return;
            
            // if the node marked as selected is wrong
            if(selectedLI.id.substr(4) != tree_selectedCategoryNo)
            {
                // remove the tm_selected class from the currently selected node
                selectedLI.className = selectedLI.className.replace('tm_selected', '');
				var newSelectedLI  = document.getElementById('cat_'+tree_selectedCategoryNo);
				if(newSelectedLI)
				{
					newSelectedLI.className += " tm_selected";
					tree_selectedId = newSelectedLI.id;	
				}	
            }
            else
            {
                // ensure that the selected node has the tm_selected class applied
                if(selectedLI.className.indexOf('tm_selected') == -1 )
                {
                    // apply the tm_selected class to the correct LI
                    selectedLI.className += " tm_selected";
                }
                
                // update the selected id
                tree_selectedId = selectedLI.id;
            }
        }
		
	 /*    =========================================================
		tree_hiddenSubtreeNodes()
		hidden the subtree, when the node is closed
           =========================================================  */
		function tree_hiddenSubtreeNodes(categoryNo)
		{
			
			var parentNode = document.getElementById('branch_'+categoryNo);
			
			if( !parentNode )
				return;
				
			var treeChildNodes = parentNode.childNodes;
			var len = treeChildNodes.length;
			var lenChild = 0;
			var id   = '';
			var idNr = '-1'
			var link = null; 
			for (var i= 0;i<len; i++)
			{
				id   = treeChildNodes[i].id;
				idNr = id.substring(id.indexOf('_')+1,id.length);
				link = document.getElementById('link_'+idNr);
				if(link)
				{
					if(link.href.indexOf('tree_nodeIsSelected=1') !=-1)	
					{
						link.href = link.href.replace('tree_nodeIsSelected=1','tree_nodeIsSelected=0');
						link.className = 'tm_closed';
					}	
				}
				if(treeChildNodes[i].className.indexOf('tm_opened') != -1 || treeChildNodes[i].className.indexOf('tm_selected') != -1)
				{
					treeChildNodes[i].className = treeChildNodes[i].className.replace('tm_opened', 'tm_closed');
					treeChildNodes[i].className = treeChildNodes[i].className.replace('tm_selected', '');		
				}					
								
			}	
			
			var urlCS =  urlChangeSession + "?categoryNoRemove=" + categoryNo +"&rdParam=" +Math.random()*10000;
		    tree_sendAjaxRequest(urlCS);
			
				
		}
    
		  /*    =========================================================
		tree_checkSibilings()
		check to see if any sibilings of the current selected node have childrends that are checked
           =========================================================  */
		function tree_checkSibilings(categoryNo)
		{
			var currentChildNode = document.getElementById("cat_"+categoryNo);
            var parentNode   = currentChildNode.parentNode;
			
			if(parentNode.id.indexOf('branch_')==-1)
				return;
				
			var nodes =  parentNode.childNodes;
			var nodesCount = nodes.length;
			var minId = '-1';
            var currentId = '';	
           	
            tree_selectedCategoryNo = categoryNo;
			
			for(var i=0;i<nodesCount;i++)
			{
				currentId = nodes[i].id;
				if((nodes[i].className.indexOf('tm_opened') != -1 || nodes[i].className.indexOf('tm_selected') != -1) && currentId!=currentChildNode.id)
				{
					minId =  currentId.substring(currentId.indexOf('_')+1,currentId.length)
					nodes[i].className = nodes[i].className.replace('tm_opened', 'tm_closed');
					nodes[i].className = nodes[i].className.replace('tm_selected', '');
					link = document.getElementById('link_'+minId);
					if(link)
					{
						if(link.href.indexOf('tree_nodeIsSelected=1') !=-1)	
						{
							link.href = link.href.replace('tree_nodeIsSelected=1','tree_nodeIsSelected=0');
						}	
					}
					
					//try to find all the children of thid node that may be openend
					var parentChildNode = document.getElementById('branch_'+minId);
					var allChildNodes = null;
					var countChildNodes  = 0;
					var k =-1;
					
					while(parentChildNode)
					{
						allChildNodes = parentChildNode.childNodes;
						countChildNodes  =  allChildNodes.length;
						for(var j=0;j<countChildNodes;j++)
						{
							k=-1;
							if(allChildNodes[j].className.indexOf('tm_selected')!=-1)
								allChildNodes[j].className = allChildNodes[j].className.replace('tm_selected', '');	
								
							if(allChildNodes[j].className.indexOf('tm_opened') != -1)
							{
								allChildNodes[j].className = allChildNodes[j].className.replace('tm_opened', 'tm_closed');
								link = document.getElementById('link_'+allChildNodes[j].id.substring(currentId.indexOf('_')+1,allChildNodes[j].id.length));
								if(link)
								{
									if(link.href.indexOf('tree_nodeIsSelected=1') !=-1)	
									{
										link.href = link.href.replace('tree_nodeIsSelected=1','tree_nodeIsSelected=0');
										link.className = 'tm_closed';
									}	
								}
								k = j;
								break;
							}
						}
						if(k==-1)
							break;
						parentChildNode = document.getElementById('branch_'+allChildNodes[k].id.substring(currentId.indexOf('_')+1,allChildNodes[k].id.length));
			
					}
					
					break;
				}				
			}				
			var urlCS ='';
			if(!isNaN(parseInt(minId)) && minId !=-1)
			{
				urlCS =  urlChangeSession + "?categoryNoRemove=" + minId +"&categoryNoAdd="+categoryNo+"&rdParam=" +Math.random()*10000;
			}
			else if(!currentChildNode.getAttribute('loaded'))
			{
				if(!reguestCategoryNo)
					urlCS =  urlChangeSession + "?categoryNoAdd="+categoryNo+"&rdParam=" +Math.random()*10000; 
				else
				{
					var arrPath = reguestCategoryNo.split(',');
					if(arrPath.indexOf(categoryNo)==-1)
						urlCS =  urlChangeSession + "?categoryNoAdd="+categoryNo+"&rdParam=" +Math.random()*10000; 
				}
				
			}
			
			if(urlCS != '')
					tree_sendAjaxRequest(urlCS);
			
		}  
    
     /*    =========================================================
        tree_sendAjaxRequest()
        =========================================================  */ 	
	function tree_sendAjaxRequest(url)
	{
		ajaxSessionRequest = Ajax.getTransport();
			
		if( ajaxSessionRequest )
		{   
			ajaxSessionRequest.open( "GET", url, true );
			ajaxSessionRequest.onreadystatechange = function() {
				if(ajaxSessionRequest.readystate == 4 && ajaxSessionRequest.status != 200)
					{ 
						alert('Ajax unknowing error.');
					}
				};
					ajaxSessionRequest.send( "" );
		}
		else
			alert('No AJAX transport found!');	
	}
        
    /*    =========================================================
        tree_setNodeExpansionQueue()
        Stores an array of nodes to open progressively.
        =========================================================  */
        function tree_setNodeExpansionQueue(categoryNos)
        {
            tree_categoriesToExpand = categoryNos;
        }
		
		function tree_appendToNodeExpansionQueue(categoryNos)
        {
            tree_categoriesToExpand = tree_categoriesToExpand.concat( categoryNos );    
        }
        
    /*    =========================================================
        tree_expandNextInQueue()
        pos the last category in queue and expands it
        =========================================================  */
        function tree_expandNextInQueue()
        {
            if(tree_categoriesToExpand.length < 1)
                return false;
            
            // get and remove the first category number
            var catNo = tree_categoriesToExpand.shift();
            
            // Expand ithe category
            leafClick(null, catNo,'', true, reqCNo);
        }
        
    /*    =========================================================
        showAjaxError()
        Opens a new window and loads the error page caused by the Ajax
        server side code.
        =========================================================  */
        function showAjaxError(ajaxRequest)
        {
            var newWindow = window.open('','','location=no, menubar=no, toolbar=no, status=no');
            var oNewDoc = newWindow.document.open("text/html", "replace");
            var sMarkup = "<html><head><title>AJAX Response</title></head><body>"+ajaxRequest.responseText+"</body></html>";
            oNewDoc.write(sMarkup);
            oNewDoc.close();
        }
        
        
        