
function TOCTree ( winTOC, winContent )
{

	if ( !TOCTree.bInitialized )
		TOCTree.initTOCTreeClass();
	
	if ( winTOC && winTOC.TheTOCTree )
	{
		return winTOC.TheTOCTree ;
	}
	this.m_winTOC = winTOC;
	this.m_winContent = winContent;
	this.m_docTOC = null;
	
	this.m_bSyncTOCWithContent = false ;
	this.m_ContentHREFToTOCLinkMap = null ;
	this.m_bHiliteCurLink = false ;
	this.m_hiColor = "";
	this.m_hiBGColor = "green";
	this.m_imgOpenSrc = "" ;
	this.m_imgCloseSrc = "" ;
	this.m_imgLeafSrc = "" ;
	
	this.m_nSyncInterval = 0;	
	
	this.m_nYOffset = 0 ;		
	
	this.m_nIndentDelta = 10 ;	
	this.m_nXOffset = 18;		
	this.m_basePath = "";
	
	this.m_bInitialized = false ;
	this.m_curFolderID = -1 ;		
	this.m_curHiliteFolderID = "" ;	
	this.m_curBODYLocation = "";	
	
	this.m_bDoArrowKeyNav = true ;
	this.m_origKeyDownHandler = null ;
	this.m_origKeyPressHandler = null;
	this.m_syncTimeoutId = null ;
	
	this.m_imgOpen = null;
	this.m_imgClose = null;
	
	if ( this.m_winTOC )
	{
		this.m_winTOC.TheTOCTree = this;
	}
	return this;
}	
TOCTree.HiliteId = "THEHILITE";
TOCTree.initTOCTreeClass = function ()
{

	if ( ! isXblibInit ) xblibInit();
	
	if ( isNav4 )
	{
		TOCTree.prototype.applyHilite = applyHilite_Nav4;
		TOCTree.prototype.removeHilite = removeHilite_Nav4;
	}
	else if ( isIE4 )
	{
		TOCTree.prototype.applyHilite = applyHilite_IE4;
		TOCTree.prototype.removeHilite = removeHilite_IE4;
	}
	else
	{
		TOCTree.prototype.applyHilite = applyHilite_W3C;
		TOCTree.prototype.removeHilite = removeHilite_W3C;
	}
	TOCTree.bInitialized = true ;
}
TOCTree.initTOCTreeClass();
TOCTree.prototype.initialize = function ()
{

	this.m_docTOC = this.m_winTOC.document;
	this.m_imgOpen = new Image(); 
	this.m_imgClose = new Image(); 
	this.m_imgOpen.src = this.m_basePath + this.m_imgOpenSrc ;
	this.m_imgClose.src = this.m_basePath + this.m_imgCloseSrc ;
	this.m_bInitialized = true ;
	
	
	if ( this.m_bDoArrowKeyNav )
	{
		this.m_winTOC._onDocKeyDown = getInstanceEventHandler( this, "onDocKeyDown" );
		this.m_origKeyDownHandler = addEvent( this.m_docTOC, "keydown", 
			this.m_winTOC._onDocKeyDown, 1, (isNav4 ? Event.KEYDOWN : null) );
		
		if ( isMoz5 )
		{
			
			this.m_winTOC._onDocKeyPress = getInstanceEventHandler( this, "onDocKeyPress" );
			this.m_origKeyPressHandler = addEvent( this.m_docTOC, "keypress", 
				this.m_winTOC._onDocKeyPress, 1 );
		}
	}
	
	if ( isNav4 )
	{
		this.m_winTOC.captureEvents( Event.RESIZE );
		this.m_winTOC.onresize = function(){location.reload();return false;};
	}
	if ( isNav4 )
	{
		
		var nextY =	this.m_nYOffset ;
		var folder = this.getFolderFromID( "z0" );
		var exposedHeight = this.m_nYOffset + folder.clip.height ; 
		var iter = new FolderIter( folder );
		while ( folder )
		{
			if ( iter.curLevel() == this.m_nXOffset )
			{
				folder.pageY = nextY ;
				folder.visibility = "show";
				nextY += folder.document.height ;
				exposedHeight += folder.clip.height ;
			}
			folder = iter.getNext();
		}

		
		this.m_docTOC.height = exposedHeight;

		
		if ( this.m_bHiliteCurLink )
		{
			this.m_hiliteDiv = this.m_docTOC[ TOCTree.HiliteId ];
			if ( ! this.m_hiliteDiv )
			{
				alert( "HILITING TURNED ON BUT NO HILITER WAS FOUND - insert call to TOCTree.createHiliter inside <BODY>" ); 
			}
		}
	}
	if ( this.m_bSyncTOCWithContent )
	{
		this.m_syncTimeoutId = this.m_winTOC.setTimeout( "TheTOCTree.syncTOC()", this.m_nSyncInterval );
	}

}	

TOCTree.createHiliter = function ( docObj, imgSrc )
{
	if ( isNav4 )
	{
		docObj.write( '<layer style="position:absolute;left:0;padding:0;margin:0;width=100%;visibility:hidden;" id="' + TOCTree.HiliteId + '"><IMG SRC="' + imgSrc + '"></layer>' );
		var div = docObj[ TOCTree.HiliteId ];
		if ( div )
		{
			div.visibility = "hidden" ;
		}
	}
}
TOCTree.prototype.onError = function ( msg, url, line )
{
	
	if ( isMoz5 ) return true ;
	if ( -1 != msg.search( /access disallowed|permission denied/i ) )
	{
		this.m_syncTimeoutId = this.m_winTOC.setTimeout( "TheTOCTree.syncTOC()", this.m_nSyncInterval );
		return true ;
	}
	alert( "JavaScript Error:\n" + msg + "\n\nIn file:\t" + url + "\n\nLine No.:\t" + line );
	return true ;
}

TOCTree.prototype.hiliteFolder = function ( folder )
{
	if ( !(folder && this.m_bHiliteCurLink) ) return ;

	
	if ( this.isFolderVisible( folder ) && 
		 (this.m_curHiliteFolderID == folder.id) )
	{

		return ;
	}
	var curHiliteFolder = this.getFolderFromID( this.m_curHiliteFolderID );
	
	if ( curHiliteFolder )
	{
		this.removeHilite( curHiliteFolder );
		this.m_curHiliteFolderID = "" ;
	}
	
	var iter = new FolderIter( folder );
	while ( folder )
	{
		if ( this.isFolderVisible( folder ) )
			break;
		folder = iter.getParent();
	}
	if ( folder )
	{
		this.applyHilite( folder );			
		this.m_curHiliteFolderID = folder.id ;
	}
	else{}
}	 
function applyHilite_IE4 ( folder )
{
	if ( this.m_hiColor )
		folder.children[ folder.children.length - 1 ].style.color = this.m_hiColor ;
	if ( this.m_hiBGColor )
		folder.children[ folder.children.length - 1 ].style.backgroundColor = this.m_hiBGColor ;
}	
function applyHilite_Nav4 ( folder )
{
	this.m_hiliteDiv.visibility = "show" ;
	this.m_hiliteDiv.moveBelow( folder );
	this.m_hiliteDiv.moveTo( 0, folder.top );
}	
function applyHilite_W3C ( folder )
{
	if ( this.m_hiColor )
		folder.lastChild.style.color = this.m_hiColor ;
	if ( this.m_hiBGColor )
		folder.lastChild.style.backgroundColor = this.m_hiBGColor ;
}	
function removeHilite_IE4 ( folder )
{
	folder.children[ folder.children.length - 1 ].style.color = "" ;
	folder.children[ folder.children.length - 1 ].style.backgroundColor = "" ;
}	
function removeHilite_Nav4 ( folder )
{
	this.m_hiliteDiv.visibility = "hide" ;
}	
function removeHilite_W3C ( folder )
{
	folder.lastChild.style.color = "" ;
	folder.lastChild.style.backgroundColor = "" ;
}	

TOCTree.prototype.exposeFolder = function ( folder )
{
	if ( ! folder ) return ;
	if ( ! this.isFolderVisible( folder ) )
	{
		var iter = new FolderIter( folder );
		var parentFolder = iter.getParent();
		while ( parentFolder )
		{
			if( ! this.isFolderOpen( parentFolder ) )
			{
				this.tf( null, parentFolder );
			}
			parentFolder = iter.getParent();
		}
	}
	if ( ! isElemInView( folder, this.m_winTOC ) )
	{
		scrollVertToElem( folder, this.m_winTOC );		
	}
}
TOCTree.prototype.isFolderOpen = function ( folder )
{
	if ( isNav4 )
	{
		return ( -1 != folder.document.images[ 0 ].src.indexOf( this.m_imgOpenSrc ) );
	}
	else
	{
		return (1 == this.getFolderStatus( folder ));
	}
}
TOCTree.prototype.getFolderStatus = function ( folder )
{
	if ( folder.folderStatus == null )
	{
		
		var imgSrc = "";
		if ( isIE4 )
		{
			
			if ( ("IMG" == folder.children[ 0 ].tagName) ||
				 (("A"  == folder.children[ 0 ].tagName) &&
				  (! folder.children[ 0 ].href)) )
			{
				return (folder.folderStatus = 0);
			}
			else	
			{
				imgSrc = folder.children[ 0 ][ 0 ].src ;
			}
		}
		else
		{
			
			if ( ("IMG" == folder.firstChild.tagName) ||
				 (("A"  == folder.firstChild.tagName) &&
				  (! folder.firstChild.href)) )
			{
				return (folder.folderStatus = 0);
			}
			else	
			{
				imgSrc = folder.firstChild.firstChild.src ;
			}
		}
		if ( -1 != imgSrc.indexOf( this.m_imgOpenSrc )  )
		{
			folder.folderStatus = 1;
		}
		else if ( -1 != imgSrc.indexOf( this.m_imgCloseSrc ) )
		{
			folder.folderStatus = -1;
		}
	}
	return folder.folderStatus;	
}
TOCTree.prototype.isFolderClosed = function ( folder )
{
	if ( isNav4 )
	{
		return ( -1 != folder.document.images[ 0 ].src.indexOf( this.m_imgCloseSrc ) );
	}
	else
	{
		return  (-1 == this.getFolderStatus( folder ));
	}
}
TOCTree.prototype.isLeafFolder = function ( folder )
{
	if ( isNav4 )
	{
		return ( -1 != folder.document.images[ 0 ].src.indexOf( this.m_imgLeafSrc ) );
	}
	else
	{
		return (0 == this.getFolderStatus( folder ));
	}
}
TOCTree.prototype.openFolder = function ( folder )
{
	var img ;
	if ( isNav4 )
	{
		img = folder.document.images[ 0 ];
	}
	else
	{
	 	folder.folderStatus = 1;
		if ( isIE4 )
		{
			img = folder.children[ 0 ][ 0 ];
		}
		else
		{
			img = folder.firstChild.firstChild;
		}
	}
	if ( img )
		img.src = this.m_imgOpen.src ;
}
TOCTree.prototype.closeFolder = function ( folder )
{
	var img ;
	if ( isNav4 )
	{
		img = folder.document.images[ 0 ];
	}
	else
	{
	 	folder.folderStatus = -1;
		if ( isIE4 )
		{
			img = folder.children[ 0 ][ 0 ];
		}
		else
		{
			img = folder.firstChild.firstChild;
		}
	}
	if ( img )
		img.src = this.m_imgClose.src ;
}
TOCTree.prototype.hideFolder = function ( folder )
{
	if ( isNav4 )
	{
		folder.visibility = "hide" ;	
	}
	else
	{
		folder.style.display = "none";
	}
}
TOCTree.prototype.isFolderVisible = function ( folder )
{
	if ( isNav4 )
	{
		return ( "show" == folder.visibility );
	}
	else
	{
		
		if ( 0 == parseInt( folder.className.slice(1) ) )
		{
			return true ;
		}
		return ( "block" == folder.style.display );
	}
}
TOCTree.prototype.showFolder = function ( folder )
{
	if ( isNav4 )
	{
		folder.visibility = "show" ;
	}
	else
	{
		folder.style.display = "block";
	}
}
TOCTree.prototype.isRootFolder = function ( folder )
{
	if ( isNav4 )
	{
		return (this.m_nXOffset == folder.left);
	}
	else
	{
		return (0 == parseInt( folder.className.slice(1) ));
	}
}	


TOCTree.prototype.onDocKeyDown = function ( e )
{
	var keyCode = ( isIE ? this.m_winTOC.event.keyCode : e.which );
	if ( isNav4 )
	{
		
		switch( keyCode )
		{
			case 39: keyCode = 40; break;
			case 91: keyCode = 37; break;
			case 93: keyCode = 39; break;
			case 61: keyCode = 38; break;
		}
	}

	var bOurKey = true ;
	var folder = this.getFolderFromID( 'z' + this.m_curFolderID );
	if ( ! folder )
	{
		bOurKey = false;
	}
	else
	{
		var iter = new FolderIter( folder );
		switch( keyCode )
		{
			case 38:

				
				var prevFolder = iter.getPrev();
				while ( prevFolder )
				{
					if ( this.isFolderVisible( prevFolder ) )
					{
						break;
					}
					prevFolder = iter.getPrev();
				}
				this.selectFolder( prevFolder );
				break;
			case 40:

				
				var nextFolder = iter.getNext();
				while ( nextFolder )
				{
					if ( this.isFolderVisible( nextFolder ) )
					{
						break;
					}
					nextFolder = iter.getNext();
				}
				this.selectFolder( nextFolder );
				break;
			case 37:

				
				if ( this.isFolderOpen( folder ) )
				{
					this.tf( null, folder );
					if ( ! isNav4 )
					{
						var link = this.getFolderLink( folder );
						if ( link && link.href )
						{
							link.focus();
						}
					}
				}
				else	
				{
					this.selectFolder( iter.getParent() );
				}
				break;
			case 39:

				
				if ( this.isFolderClosed( folder ) )
				{
					this.tf( null, folder );
					if ( ! isNav4 )
					{
						var link = this.getFolderLink( folder );
						if ( link && link.href )
						{
							link.focus();
						}
					}
				}
				else	
				{
					this.selectFolder( iter.getNextChild() );
				}
				break;
			default:

				bOurKey = false ;
				break;
		}
	}
	if ( bOurKey )
	{
		return cancelEvent( e );
	}
	else
	{
		if ( this.m_origKeyDownHandler )
		{
			return this.m_origKeyDownHandler( e );
		}
		if ( isNav4 )
			this.m_docTOC.routeEvent( e );
		return true ;
	}
}	
TOCTree.prototype.onDocKeyPress = function ( e )
{
	if ( ! isMoz5 ) return true;
	var keyCode = e.keyCode;
	var bOurKey = false ;
	switch( keyCode )
	{
		case 37:
		case 38:
		case 39:
		case 40:
			bOurKey = true ;
			break;
		default:
			break;
	}
	if ( bOurKey )
	{
		return cancelEvent( e );
	}
	else
	{
		if ( this.m_origKeyPressHandler )
		{
			return this.m_origKeyPressHandler( e );
		}
		return true ;
	}
}	

TOCTree.prototype.tf = function ( folderID, folder, nForce, bNoHilite )
{
	if ( ! this.m_bInitialized ) return ;
	
	if ( parseInt( folderID ) == folderID )
	{
		folderID = 'z' + folderID;
	}
	if ( ! folder ) folder = this.getFolderFromID( folderID );
	if ( ! folder ) return ;
	if ( ! folderID ) folderID = folder.id ;
	var fForceClose = false;
	var fForceOpen = false;
	if ( nForce == 1 )
	{
		fForceOpen = true;
	}
	else if ( nForce == -1 )
	{
		fForceClose = true;
	}

	var fShow ;
	if ( this.isFolderOpen( folder ) || fForceClose )
	{
		fShow = false ;
		this.closeFolder( folder );
	}
	else
	{
		fShow = true ;
		this.openFolder( folder );
	}
	var iter = new FolderIter( folder );
	if ( isNav4 )
	{
		var fKeepToggling = true ;
		var	startY, exposedHeight = 0;
		var folderHeight = folder.clip.height ;
		var startHeight = ( folder.top + folderHeight );
		var nextY = startHeight;
		folder = iter.getNext();
		while( folder )
		{
			if ( fKeepToggling )
			{
				if ( iter.startLevel() >= iter.curLevel() )
				{
					fKeepToggling = false ;
				}
				else
				{
					if ( ! fShow )
					{
						this.hideFolder( folder );
						if ( this.isFolderOpen( folder ) )
							this.closeFolder( folder );
					}
					else if ( (iter.startLevel() + this.m_nIndentDelta) == iter.curLevel() )
					{
						 
						this.showFolder( folder );
					}
				}
			}
			if ( folder.visibility != "hide" )
			{
				folder.top = nextY ;
				exposedHeight += folder.clip.height ;
				nextY = folder.top + folder.clip.height ;
			}
			folder = iter.getNext();
		}
		
		this.m_docTOC.height = startHeight + exposedHeight + folderHeight ;
	}
	else
	{
		
		folder = iter.getNextChild();
		while( folder )
		{
			if ( !fShow )
			{
				this.hideFolder( folder );
				if ( this.isFolderOpen( folder ) )
					this.closeFolder( folder );
			}
			else if ( iter.curLevel() == (iter.startLevel() + 1) )
			{
				this.showFolder( folder );
			}
			folder = iter.getNextChild();
		}
	}
	
	if ( !bNoHilite )
	{
		this.hiliteFolder( this.getFolderFromID( 'z' + this.m_curFolderID ) );
	}
}	
TOCTree.prototype.toggleAll = function ( fShow, toggleDepth )
{
	if ( ! this.m_bInitialized ) return ;

 	
	var folder = this.getFolderFromID( "z0" );
	var iter = new FolderIter( folder );
	var level, isOpen;
	while ( folder )
	{
		if ( ! this.isLeafFolder( folder ) )
		{
			isOpen = this.isFolderOpen( folder );
			if ( (toggleDepth == null) || (toggleDepth < 0) )
			{
				if ( fShow )
				{
					
					if ( ! isOpen )
					{
						this.tf( folder.id, folder, 1, 1 );
					}
				}
				else if ( isOpen )
				{
					this.tf( folder.id, folder, -1, 1 );
				}
			}
			else	
			{
				level = getFolderLevel( folder );
				if ( isNav4 ) 
				{
					level = (level - this.m_nXOffset) / this.m_nIndentDelta ;
				}
				if ( fShow )
				{
					
					if ( (!isOpen) && (level <= toggleDepth) )
					{
						this.tf( folder.id, folder, 1, 1 );
					}
					else if ( isOpen && (level > toggleDepth) )
					{
						this.tf( folder.id, folder, -1, 1 );
					}
				}
				else
				{
					if ( isOpen && (level >= toggleDepth) )
					{
						this.tf( folder.id, folder, -1, 1 );
					}
					else if ( (!isOpen) && (level < toggleDepth) )
					{
						this.tf( folder.id, folder, 1, 1 );
					}
				}
			}
		}
		folder = iter.getNext();
	}
	
	this.hiliteFolder( this.getFolderFromID( 'z' + this.m_curFolderID ) );

}	


TOCTree.prototype.si = function ( href, bExposeFolder )
{

	if ( ! href ) return ;
	
	var a = href.split( ":" );
	var folderId = a[ 1 ];
 	if ( folderId != null )
	{
		var folder = this.getFolderFromID( "z" + folderId );
		if ( bExposeFolder ) 
			this.exposeFolder( folder );
 		this.hiliteFolder( folder );
		this.m_curFolderID = folderId ;
	}
	if ( a[ 0 ] )
	{
		var newPath = this.m_basePath + a[ 0 ];
		if ( isMoz5 )
		{

			
			var l = this.m_winContent.location;
			if ( ! l.pathname )
			{
				
				l = this.m_winTOC.location;
			}
			
			newPath = l.href.replace( /[^\\\/]*$/, newPath );
		}
		this.m_winContent.location = newPath;
		this.m_curBODYLocation = a[ 0 ];
	}
}	
TOCTree.prototype.selectFolder = function ( folder )
{

	if ( ! folder ) return;
	var link = this.getFolderLink( folder );
	if ( ! (link && link.href) )
	{
	 return ;	
	}
	var href = link.href;
	var pos = href.search( /[\/\\][^\/\\]*$/ );
	if ( -1 != pos )
	{
		href = href.slice( pos + 1 );
	}
	if ( href && 
		(-1 != href.search( /(si|tf|toggleAll)\(/ )) &&
		(-1 == href.search( /javascript/i )) )
	{

		eval( "this." + href );
		if ( !isNav4 )
		{
			link.focus();
		}
	}
}
TOCTree.prototype.getFolderLink = function ( folder, linkIndex )
{
	if ( !folder ) return "" ;
	var links = (isNav4 ? folder.document.links : getTags( folder, "A" ) );
	if ( !links ) return "" ;

	
	if ( !linkIndex ) linkIndex = 1;

	return links[ linkIndex ];
}	
TOCTree.prototype.lookUpHREFID = function ( href )
{
	if ( ! (href && this.m_ContentHREFToTOCLinkMap) ) return null;
	var id = this.m_ContentHREFToTOCLinkMap[ href ];
	if ( null == id )
	{
		
		var path = href;
		var anchorName = "";
		var aTmp = href.split( /#/ );
		if ( aTmp && aTmp[ 1 ] )
		{
			path = aTmp[0];
			anchorName = aTmp[1];
		}

		
		if ( isW3C && anchorName )
		{
			var MAX_NODE_SEARCH = 10;
			var anchor = getElem( anchorName, this.m_winContent.document );
			if ( anchor && ("A" == anchor.tagName) )
			{
				var searchCount = 0;
				anchor = (anchor.previousSibling ? anchor.previousSibling : anchor.parentNode);
				while ( anchor && (searchCount < MAX_NODE_SEARCH) )
				{
					if ( (1 == anchor.nodeType) && 
						 ("A" == anchor.tagName) &&
						 anchor.getAttribute("Name") )
					{
						id = this.m_ContentHREFToTOCLinkMap[ path + "#" + anchor.getAttribute("Name") ];
						if ( id ) 
						{
							break;
						}
					}

					
					anchor = (anchor.previousSibling ? anchor.previousSibling : anchor.parentNode);
					searchCount++;
				}
			}
		}
		if ( null == id )
		{
			
			id = this.m_ContentHREFToTOCLinkMap[ path ];
		}
	}
	return id ;

}	
TOCTree.prototype.syncTOC = function ()
{
	
	var newLoc = this.m_winContent.location.pathname + this.m_winContent.location.hash;
	
	var pos = newLoc.search( /[\/\\][^\/\\]*$/ );
	if ( -1 != pos )
	{
		newLoc = newLoc.slice( pos + 1 );
	}
	if ( newLoc != this.m_curBODYLocation )
	{
		this.m_curBODYLocation = newLoc ;
		
		var id = this.lookUpHREFID( newLoc );
		if ( id != null )
		{

			var folder = this.getFolderFromID( "z" + id );
			if ( folder )
			{
				this.exposeFolder( folder );
				this.hiliteFolder( folder );
				this.m_curFolderID = id ;
			}
		}
	}
	this.m_syncTimeoutId = this.m_winTOC.setTimeout( "TheTOCTree.syncTOC()", this.m_nSyncInterval );
}	
TOCTree.prototype.getFolderFromID = function ( folderID )
{
	return getElem( folderID, this.m_docTOC );
}
function FolderIter ( startFolder )
{
	this.m_startFolder = startFolder;
	this.m_curFolder = startFolder;
	this.m_startLevel = this.m_curLevel = getFolderLevel( startFolder );
	return this ;
}	
FolderIter.prototype.startFolder = function ()
{
	return this.m_startFolder ;
}
FolderIter.prototype.curFolder = function ()
{
	return this.m_curFolder ;
}
FolderIter.prototype.startLevel = function ()
{
	return this.m_startLevel ;
}
FolderIter.prototype.curLevel = function ()
{
	return this.m_curLevel ;
}
FolderIter.prototype.getNext = function ()
{
	if ( ! this.m_curFolder ) return null;
	var folder;
	if ( ! isIE4 )
	{
		folder = ( isNav4 ? this.m_curFolder.above : this.m_curFolder.nextSibling );
		while ( folder )
		{
			if ( isFolder( folder ) )
			{
				break;
			}
			folder = ( isNav4 ? folder.above : folder.nextSibling );
		}
	}
	else	
	{
		for ( var i = this.m_curFolder.sourceIndex + 1; i < all.length; i++ )
		{
			folder = all[ i ];
			if ( isFolder( folder ) )
			{
				break ;
			}
		}
	}
	if ( folder )
		this.m_curLevel = getFolderLevel( folder );
	return this.m_curFolder = folder;
}	
FolderIter.prototype.getPrev = function ()
{
	if ( ! this.m_curFolder )
	{
		return null;
	}
	var folder;
	if ( ! isIE4 )
	{
		folder = ( isNav4 ? this.m_curFolder.below : this.m_curFolder.previousSibling );
		while ( folder )
		{
			if ( isFolder( folder ) )
			{
				break;
			}
			folder = ( isNav4 ? folder.below : folder.previousSibling );
		}
	}
	else	
	{
		for ( var i = this.m_curFolder.sourceIndex-1; i >= 0; i-- )
		{
			folder = all[ i ];
			if ( isFolder( folder ) )
			{
				break ;
			}
		}
	}
	if ( folder )
		this.m_curLevel = getFolderLevel( folder );
	return this.m_curFolder = folder;
}	
FolderIter.prototype.getParent = function ()
{
	var level ;
	var iter = new FolderIter( this.m_curFolder );
	var folder = iter.getPrev();
	while ( folder )
	{
		level = getFolderLevel( folder );
		if ( level < this.m_curLevel )
		{
			break;
		}
		folder = iter.getPrev();
	}
	this.m_curLevel = level;
	return this.m_curFolder = folder;
}	
FolderIter.prototype.getNextSibling = function ()
{
	var level ;
	var iter = new FolderIter( this.m_curFolder );
	var folder = iter.getNext();
	while ( folder )
	{
		level = getFolderLevel( folder );
		if ( this.m_curLevel == level )
		{
			break ;
		}
		else if ( this.m_curLevel > level )
		{
			folder = null;
			break ;
		}
		folder = iter.getNext();
	}
	this.m_curLevel = level;
	return this.m_curFolder = folder;
}	

FolderIter.prototype.getNextChild = function ()
{
	if ( ! this.m_curFolder ) return null;
	var iter = new FolderIter( this.m_curFolder );
	var folder = iter.getNext();
	var level = iter.curLevel();
	this.m_curFolder = (this.m_startLevel < level ? folder : null);
	this.m_curLevel = level;
	return this.m_curFolder ;
}	

function isFolder ( folder )
{
	if ( null == folder ) return false ;
	if ( isNav4 )
	{
		return ( "z" == folder.name.charAt( 0 ) );
	}
	else
	{
		return ( folder.tagName && 
			    (folder.tagName == "DIV") &&
		        ("z" == folder.id.charAt(0)) );
	}
}	
function getFolderLevel ( folder )
{
	return ( 
		isNav4 ?
		folder.left :
		parseInt( folder.className.slice(1) ) );
}

