/******************************************************************************
 * Common functions
 *****************************************************************************/
	
	// Select all items of a folder
	TTCheckboxList_selectAllItems = function(chekbox,id,name)
	{
		var f = document.formReen;
		var i = 0;
		var val = "";
		
		btAll = document.getElementById(name+"_checkall_"+chekbox);
		if(chekbox == "open")
			document.getElementById(name+"_checkall_close").checked = btAll.checked;
		else if(chekbox == "close")
			document.getElementById(name+"_checkall_open").checked = btAll.checked;
			
		while(true)
		{
			//document.title = i;
			val = document.getElementById(id+"-"+i);
			if (val == undefined)
      		{
        		break ;
      		}
      		//val.checked = btAll.checked;
      		val.select(btAll.checked);
			i++;			
		}		
	}
	
	// Opens a folder in the TTCheckboxList control.
	function TTCheckboxList_OpenFolder( id ) {
		var div1 = document.getElementById( id + "-close" );
		var div2 = document.getElementById( id + "-open" );

		if ( div1 != null && div2 != null ) {
			div1.style.display = "none";
			div2.style.display = "";
		}
	}
	
	// Closes a folder in the TTCheckboxList control.
 	function TTCheckboxList_CloseFolder( id ) {
		var div1 = document.getElementById( id + "-open" );
		var div2 = document.getElementById( id + "-close" );

		if ( div1 != null && div2 != null ) {
			div1.style.display = "none";
			div2.style.display = "";
		}
	}
	
	// Writes a specified text to the "debug" DIV tag:
 	function TTCheckboxList_Debug( text ) {
		var div = document.getElementById( "debug" );
		if ( div != null ) div.innerHTML += text + "<br/>";
	}
	
	// custom string comparison function to handle unicode characters, returns str1 > str2 basically
	function strCompare_UniCode(str1, str2) {
		var minLength;
		str1 = str1.toLowerCase();
		str2 = str2.toLowerCase();
		if (str1.length < str2.length) minLength = str1.length; else minLength = str2.length;		 
		for (var i=0;i<minLength-1;i++)
		{		
			if (str1.charCodeAt(i) == str2.charCodeAt(i)) continue;
			return(mapUnicodeChar(str1.charCodeAt(i)) > mapUnicodeChar(str2.charCodeAt(i)));
		}		
		return (str1.length > str2.length);
	}
	
	function mapUnicodeChar(chrCode)
	{
		switch(chrCode)
		{	
			case 224: return 97.1;	
			case 225: return 97.2;  
			case 226: return 97.3;  
			case 228: return 97.4; 			 
			case 229: return 97.5;  
			case 230: return 97.7;  
			case 231: return 99.5;  
			case 232: return 100.3; 
			case 233: return 100.5; 
			case 234: return 100.7;
			case 244: return 110.3; 
			case 246: return 110.5; 
			case 214: return 110.5;			
			case 252: return 117.5; 
			default:  return chrCode;														
		}
	}

/******************************************************************************
 * TTCheckboxList
 *****************************************************************************/

	/*
	Creates a new instance of the TTCheckboxList class.
	folders ... Array of folders to add to the TTCheckboxList class.
	items ... Array of top-level items to add to the TTCheckboxList class.
	Each element in the "folders" array is an two-element array, containing folder name and
	array of folder items. Each element in the "items" array is a two element array containing
	item value and item name. Arrays were chosen to reduce the amount of Javascript code
	which is sent from server to initialize the TTCheckboxList on client side.
	*/ 
	function TTCheckboxList( name, folders, items ) {
		this.name = name;
		this.folders  = new Array();
		this.items    = new Array();
		this.validators = new Array();
		this.changeEventHandlers = new Array();
		this.errorEventHandlers = new Array();
		if ( window[ name ] == null ) window[ name ] = this;
		for ( var i = 0; i < folders.length; i++ ) if ( folders[ i ] != null ) this.folders.push( new TTCheckboxList_Folder( this.name, this.nextFolderID(), folders[ i ] ) );
		for ( var i = 0; i < items.length; i++ ) if ( items[ i ] != null ) this.items.push( new TTCheckboxList_Item( this.name, null, this.nextItemID(), items[ i ] ) );
	}

	TTCheckboxList.prototype.nextFolderID = function() {
		if ( this.folderCnt == null ) this.folderCnt = 0;
		return this.folderCnt++;
	}

	TTCheckboxList.prototype.nextItemID = function() {
		if ( this.itemCnt == null ) this.itemCnt = 0;
		return this.name + "--" + this.itemCnt++;
	}
	
	// Renders the contect of the TTCheckboxList control into a element with a specified ID.
	TTCheckboxList.prototype.render = function( divID ) {
		if ( divID != null ) {
			this.divID = divID;
		}

		if ( this.divID == null ) return;
		
		var html = new Array();

		// Render only items in this specific folder:
		if ( this.folderToRender != null ) {
			for ( var i = 0; i < this.folderToRender.items.length; i++ ) this.renderItem( this.folderToRender.items[ i ], html );	
		}

		// Render all folders and items:
		else {
			if ( this.renderItemsFirst ) {
				for ( var i = 0; i < this.items.length; i++ ) this.renderItem( this.items[ i ], html );	
				for ( var i = 0; i < this.folders.length; i++ ) this.renderFolder( this.folders[ i ], html );	
			}
                
			else {
				for ( var i = 0; i < this.folders.length; i++ ) this.renderFolder( this.folders[ i ], html );	
				for ( var i = 0; i < this.items.length; i++ ) this.renderItem( this.items[ i ], html );	
			}
		}

		var element = document.getElementById( this.divID );
		element.innerHTML = html.join( "" );
		this.element = element;
		
		// MSIE fix: for some reason IE does not render entire checkboxlist without this workaround.
		/*
		if ( document.all && this.folders.length > 0 && this.doMsieFix ) {
			TTCheckboxList_OpenFolder( this.folders[ 0 ].id );
			setTimeout( "TTCheckboxList_CloseFolder( '" + this.folders[ 0 ].id + "' );", 1 );
		}
		*/
		
		this.attachEvents();
		//this.attachEventsForm();
		this.onChange();
	}
	
	// Selects (checks) a specified item.
	TTCheckboxList.prototype.select = function( value, checked ) {
		var found = false;
		
		for ( var i = 0; i < this.folders.length; i++ ) {
			var folder = this.folders[ i ];
			
			for ( var j = 0; j < folder.items.length; j++ ) {
				var item = folder.items[ j ];
				if ( item.value == value ) {
					item.select( checked );
					found = true;
					//#############################################################################
					//##			MODIF CHRISTOPHE
					//#############################################################################
					//puis on test pour voir si la case all doit etre cochée
					window[item.checkBoxListName].selectAllItems('item',item.folder.folderId,item.folder.id);
					break;
				}
			}
			
			if ( found ) break;
		}

		for ( var j = 0; j < this.items.length; j++ ) {
			var item = this.items[ j ];
			if ( item.value == value ) {
				item.select( checked );
				found = true;
				break;
			}
		}
	}
	
	// Returns the list of all selected items organized into folders.
	TTCheckboxList.prototype.getSelection = function() {
		if ( this.selection == null ) {
			this.selection = new TTCheckboxList_Selection();
		
			// Get selected items from the folders:
			for ( var i = 0; i < this.folders.length; i++ ) {
				var folder = this.folders[ i ];
				var selectedFolder = null;
				
				for ( var j = 0; j < folder.items.length; j++ ) {
					var item = folder.items[ j ];
					
					if ( item.isSelected() ) {
						if ( selectedFolder == null ) {
							selectedFolder = new TTCheckboxList_Folder( this.name, folder.id, [ folder.name, [], folder.folderInfo ] );
							this.selection.folders.push( selectedFolder );
						}
						
						selectedFolder.items.push( item );
						this.selection.itemCount++;
					}
				}
			}
			
			// Get top-level selected items:
			for ( var i = 0; i < this.items.length; i++ ) {
				var item = this.items[ i ];
				if ( item.isSelected() ) {
					this.selection.items.push( item );
					this.selection.itemCount++;
				}
			}
		}
		return this.selection;
	}
	
	// Gets the comma-separated list of selected values:
	TTCheckboxList.prototype.getValue = function() {
		if ( this.value == null ) {
			var selectedValues = new Array();
			
			for ( var i = 0; i < this.getSelection().folders.length; i++ ) {
				for ( var j = 0; j < this.getSelection().folders[ i ].items.length; j++ ) {
					selectedValues.push( this.getSelection().folders[ i ].items[ j ].value );
				}
			}
			
			for ( var i = 0; i < this.getSelection().items.length; i++ ) {
				selectedValues.push( this.getSelection().items[ i ].value );
			}
			
			this.value = selectedValues.join( "," )
		}
		
		return this.value;
	}	
	
	// Attaches event handlers.
	TTCheckboxList.prototype.attachEvents = function() {
		if ( !this.disabled ) 
		{
			var checkBoxes = document.forms[ this.formID ].elements[ this.name + "_values[]" ];
			var k = 0;
			var checkBox;
			
			var onClick = function() {
				var checkBoxList = window[ this.checkBoxListName ];
				checkBoxList.selection = null;
				checkBoxList.value = null;
				if ( checkBoxList.validate() ) checkBoxList.onChange( this.getItem() );
				else this.checked = false;
				
				item = this.getItem();
				//#############################################################################
				//##			MODIF CHRISTOPHE
				//#############################################################################
				//puis on test pour voir si la case all doit etre cochée
				window[this.checkBoxListName].selectAllItems('item',item.folder.folderId,item.folder.id);
			}

			if ( this.folderToRender != null ) {
				var getItem = function() { return window[ this.checkBoxListName ].folderToRender.items[ this.itemIndex ]; }
				
				for ( var j = 0; j < this.folderToRender.items.length; j++ ) {
					checkBox = ( checkBoxes.length != null ) ? checkBoxes[ k++ ] : checkBoxes;
					this.folderToRender.items[ j ].checkBox = checkBox;
					checkBox.itemIndex = j;
					checkBox.checkBoxListName = this.name
					checkBox.getItem = getItem;
					checkBox.onclick = onClick;
				}
			}

			else {
				var getItem1 = function() { return window[ this.checkBoxListName ].folders[ this.folderIndex ].items[ this.itemIndex ]; }
				var getItem2 = function() { return window[ this.checkBoxListName ].items[ this.itemIndex ]; }

				if ( this.renderItemsFirst ) {
					for ( var j = 0; j < this.items.length; j++ ) {
						checkBox = ( checkBoxes.length != null ) ? checkBoxes[ k++ ] : checkBoxes;
						this.items[ j ].checkBox = checkBox;
						checkBox.itemIndex = j;
						checkBox.checkBoxListName = this.name
						checkBox.getItem = getItem2;
						checkBox.onclick = onClick;
					}
				}
                        
				for ( var i = 0; i < this.folders.length; i++ ) {
					var folder = this.folders[ i ];
					
					for ( var j = 0; j < folder.items.length; j++ ) {
						checkBox = ( checkBoxes.length != null ) ? checkBoxes[ k++ ] : checkBoxes;
						folder.items[ j ].checkBox = checkBox;
						checkBox.folderIndex = i;
						checkBox.itemIndex = j;
						checkBox.checkBoxListName = this.name
						checkBox.getItem = getItem1;
						checkBox.onclick = onClick;
					}
				}
                        
				if ( !this.renderItemsFirst ) {
					for ( var j = 0; j < this.items.length; j++ ) {
						checkBox = ( checkBoxes.length != null ) ? checkBoxes[ k++ ] : checkBoxes;
						this.items[ j ].checkBox = checkBox;
						checkBox.itemIndex = j;
						checkBox.checkBoxListName = this.name
						checkBox.getItem = getItem2;
						checkBox.onclick = onClick;
					}
				}
			}
		}
	}
	
	/****
	###																			###
	##																			 ##
	###																			###
		MODIF CGAUDELET
	###																			###
	##																			 ##
	###																			###
	****/
	
	// Select all items of a folder
	TTCheckboxList.prototype.selectAllItems = function(checkbox,id,name)
	{
		//cas de la case globale cochée
		if(checkbox != 'item')
		{
			var f = document.formReen;
			var i = 0;
			var val = "";
			
			btAll = document.getElementById(name+"_checkall_"+checkbox);
			if(checkbox == "open")
				document.getElementById(name+"_checkall_close").checked = btAll.checked;
			else if(checkbox == "close")
				document.getElementById(name+"_checkall_open").checked = btAll.checked;
				
			var folder = this.folders[id];
						
			for ( var j = 0; j < folder.items.length; j++ ) {
				folder.items[j].select(btAll.checked);
			}
		}
		//cas d'une seule cochée ou décochée
		else
		{
			var folder = this.folders[id];
			var trouve = false;
			var j =0;
			
			while(j < folder.items.length && !trouve) {
			
				if(!folder.items[j].isSelected())
				{
					trouve = true;
				}
				
				j++ ;
			}
			if(trouve)
			{
				document.getElementById(name+"_checkall_close").checked = false;
				document.getElementById(name+"_checkall_open").checked = false;
			}else
			{
				document.getElementById(name+"_checkall_close").checked = true;
				document.getElementById(name+"_checkall_open").checked = true;
			}
		}
	}
	
	/****
	###																			###
	##																			 ##
	###																			###
		FIN MODIF CGAUDELET
	###																			###
	##																			 ##
	###																			###
	****/
	
	// Adds the specified folders to the checkboxlist. The folders and items in the CheckBoxList 
	// should be ordered by name.
	TTCheckboxList.prototype.addFolders = function( folders ) {
		var modified = false;
		if (folders == undefined) return false;
		for ( var i = 0; i < folders.length; i++ ) {
			if ( folders[ i ] == null ) continue;
 
			// The name of the folder to insert:
			var folderName = folders[ i ][ 0 ];

			// The items in the folder to insert:
			var items = folders[ i ][ 1 ];

			// The existing or newly created folder:
			var folder = null;
			
			for ( var ii = 0; ii < this.folders.length; ii++ ) {
				// The specified folder already exists in the control, therefore we will
				// add the items to this existing folder. 
				if ( this.folders[ ii ].name.toLowerCase() == folderName.toLowerCase() ) {
					folder = this.folders[ ii ];
					
					// Add items that do not exist in the folder:
					for ( var j = 0; j < items.length; j++ ) {
						if ( items[ j ] == null ) continue;

						// The name of the item to insert:
						var itemName  = items[ j ][ 1 ];

						// The existing or newly created item:
						var item = null;
						
						for ( var jj = 0; jj < folder.items.length; jj++ ) {
							// If the item already exists in the folder, then do nothing.
							if ( folder.items[ jj ].name.toLowerCase() == itemName.toLowerCase() ) {
								item = folder.items[ jj ];
								break;
							}

							// Otherwise insert the new item to the folder.
							// We need to preserve the alphabetical order of the item names.							
							if ( strCompare_UniCode(folder.items[ jj ].name, itemName) ) {
								item = new TTCheckboxList_Item( this.name, folder, folder.nextItemID(), items[ j ] );
								folder.items.splice( jj, 0, item );
								modified = true;
								break;
							}
						}
							
						if ( item == null ) {
							item = new TTCheckboxList_Item( this.name, folder, folder.nextItemID(), items[ j ] );
							folder.items.push( item );
							modified = true;
						}
					}
					
					break;
				}
				
				// The specified folder does not exist in the checkbox list, therefore
				// we will insert the new folder with all its items. We need to preserve the alphabetical
				// order of the folder names.
				if (strCompare_UniCode(this.folders[ ii ].name, folderName)){
					folder = new TTCheckboxList_Folder( this.name, this.nextFolderID(), folders[ i ] );
					this.folders.splice( ii, 0, folder );
					modified = true;
					break;
				}
			}

			if ( folder == null ) {
				folder = new TTCheckboxList_Folder( this.name, this.nextFolderID(), folders[ i ] );
				this.folders.push( folder );
				modified = true;
			}
		}

		return modified;
	}

	// Adds the specified top-level items to the checkboxlist:
	TTCheckboxList.prototype.addItems = function( items ) {
		var modified = false;
		if (items == undefined) return false;
		for ( var j = 0; j < items.length; j++ ) {
			if ( items[ j ] == null ) continue;

			// The name of the item to insert:
			var itemName  = items[ j ][ 1 ];

			// The existing or newly created item:
			var item = null;
			
			for ( var jj = 0; jj < this.items.length; jj++ ) {
				// If the item already exists in the checkbox list, then do nothing.
				if ( this.items[ jj ].name.toLowerCase() == itemName.toLowerCase() ) {
					item = this.items[ jj ];
					break;
				}

				// Otherwise insert the new item to the checkbox list.
				// We need to preserve the alphabetical order of the item names.
				if ( this.items[ jj ].name.toLowerCase() > itemName.toLowerCase() ) {
					item = new TTCheckboxList_Item( this.name, null, this.nextItemID(), items[ j ] );
					this.items.splice( jj, 0, item );
					modified = true;
					break;
				}
			}
							
			if ( item == null ) {
				item = new TTCheckboxList_Item( this.name, null, this.nextItemID(), items[ j ] );
				this.items.push( item );
				modified = true;
			}
		}

		return modified;
	}

	// Removes folders from the checkboxlist:
	TTCheckboxList.prototype.removeFolders = function( folders ) {
		var modified = false;
		var selectionChanged = false;
		if (folders == undefined) return false;
		for ( var i = 0; i < folders.length; i++ ) {
			// The name of the folder to remove:
			var folderName = folders[ i ][ 0 ];

			// The items in the folder to remove:
			var items = folders[ i ][ 1 ];
			
			for ( var ii = 0; ii < this.folders.length; ii++ ) {
				// The folders are ordered by name, so we do not need to scan all folders:				
				if ( strCompare_UniCode(this.folders[ ii ].name, folderName) ) break;
				
				// If the specified folder exists in the control, we will
				// remove the items to this existing folder. 
				if ( this.folders[ ii ].name.toLowerCase() == folderName.toLowerCase() ) {
					var folder = this.folders[ ii ];
					
					for ( var j = 0; j < items.length; j++ ) {
						if (items[ j ]== undefined) break;
						// The name of the item to remove:
						var itemName  = items[ j ][ 1 ];
						
						for ( var jj = 0; jj < folder.items.length; jj++ ) {
							// The items are ordered by name so we do not need to scan all items.							
							if ( strCompare_UniCode(folder.items[ jj ].name, itemName) ) break;

							// If we found the item, we will remove it from the folder.
							if ( folder.items[ jj ].name.toLowerCase() == itemName.toLowerCase() ) {
								selectionChanged = selectionChanged || folder.items[ jj ].isSelected();
								folder.items[ jj ].folder = null;
								folder.items.splice( jj, 1 );
								modified = true;
								break;
							}
						}
					}

					// If there are no more items left in the folder, then remove the folder itself:
					if ( folder.items.length == 0 ) {
						this.folders.splice( ii, 1 );
						modified = true;
					}
					
					break;
				}
			}
		}

		if ( selectionChanged ) {
			this.selection = null;
			this.value = null;
			this.onChange();
		}
		
		return modified;
	}

	// Removes items from the checkboxlist:
	TTCheckboxList.prototype.removeItems = function( items ) {
		var modified = false;
		var selectionChanged = false;
		if (items == undefined) return false;
		for ( var j = 0; j < items.length; j++ ) {
			// The name of the item to remove:
			var itemName  = items[ j ][ 1 ];
			
			for ( var jj = 0; jj < this.items.length; jj++ ) {
				// The items are ordered by name so we do not need to scan all items.
				if ( this.items[ jj ].name.toLowerCase() > itemName.toLowerCase() ) break;

				// If we found the item, we will remove it from the checkboxlist.
				if ( this.items[ jj ].name.toLowerCase() == itemName.toLowerCase() ) {
					selectionChanged = selectionChanged || this.items[ jj ].isSelected();
					this.items.splice( jj, 1 );
					modified = true;
					break;
				}
			}
		}

		if ( selectionChanged ) {
			this.selection = null;
			this.value = null;
			this.onChange();
		}

		return modified;
	}

	// Removes all folders and items from the checkboxlist:
	TTCheckboxList.prototype.clear = function() {
		// Remove circular references
		for ( var i = 0; i < this.folders.length; i++ ) {
			for ( var j = 0; j < this.folders[ i ].items.length; j++ ) {
				this.folders[ i ].items[ j ].folder = null;
			}
		}

		this.folders = new Array();
		this.items = new Array();
	}

	// Unselects all selected items:
	TTCheckboxList.prototype.clearSelection = function() {
		var selectedValues = this.getValue().split( /,/g );
		for ( var i = 0; i < selectedValues.length; i++ ) this.select( selectedValues[ i ], false );
	}

	// Adds a new validator.
 	TTCheckboxList.prototype.addValidator = function( validator ) {
		this.validators.push( validator );
	}
	
	// Validates the current state of the checkBoxList.
	TTCheckboxList.prototype.validate = function() {
		for ( var i = 0; i < this.validators.length; i++ ) {
			if ( !this.validators[ i ].validate( this ) ) {
				this.onError( this.validators[ i ].errorMessage );
				this.selection = null;
				return false;
			}
		}
		
		return true;
	}

	// Adds a new event handler for the "Change" event.
 	TTCheckboxList.prototype.addChangeEventHandler = function( eventHandler ) {
		this.changeEventHandlers.push( eventHandler );
	}

	// Raises the "Change" event.
	TTCheckboxList.prototype.onChange = function( item ) {
		for ( var i = 0; i < this.changeEventHandlers.length; i++ ) {
			this.changeEventHandlers[ i ]( this, item );
		}
	}

	// Adds a new event handler for the "Error" event.
 	TTCheckboxList.prototype.addErrorEventHandler = function( eventHandler ) {
		this.errorEventHandlers.push( eventHandler );
	}
	
	// Raises the "Error" event.
	TTCheckboxList.prototype.onError = function( errorMessage ) {
		if ( this.errorEventHandlers.length > 0 ) {
			for ( var i = 0; i < this.errorEventHandlers.length; i++ ) {
				this.errorEventHandlers[ i ]( this, errorMessage );
			}
		}
		
		else {
			alert( errorMessage );
		}
	}
	
	// Handles the event when the item is programmatically selected:
	TTCheckboxList.prototype.onItemSelected = function( item ) {
		this.selection = null;
		this.value = null;
		
		if ( this.validate() ) {
			this.onChange( item );
					
			if ( item.isSelected() && this.openFolderOnSelect && item.folder != null ) {
				TTCheckboxList_OpenFolder( item.folder.id );
				//item.checkBox.focus();
			}
					
			return true;
		}
		
		return false;
	}
	
	// Specifies whether the control is disabled:
	TTCheckboxList.prototype.disabled = false;

	// Sets the "disabled" property to a specified value.
	TTCheckboxList.prototype.setDisabled = function( value ) {
		if ( this.disabled != value ) {
			this.disabled = ( value == true );
			if ( this.disabled ) this.clearSelection();
			this.render();
		}
	}

	// Defines the layout of the folder in the TTCheckboxList control.
	TTCheckboxList.prototype.folderFormatString = "<div id=\"{Folder.ID}-close\" class=\"folder\" >";
	TTCheckboxList.prototype.folderFormatString += "<div class=\"expand\" onClick=\"TTCheckboxList_OpenFolder('{Folder.ID}');\"><code>+</code></div>";
	TTCheckboxList.prototype.folderFormatString += "<div class=\"select_all_ckeckBox\"><input type=\"checkbox\" name=\"{Folder.ID}_folder\" id=\"{Folder.ID}_checkall_close\" onClick=\"{Name}.selectAllItems('close','{Folder.folderId}','{Folder.ID}');\"></div>";
	TTCheckboxList.prototype.folderFormatString += "<div class=\"cbl_folder\" onClick=\"TTCheckboxList_OpenFolder('{Folder.ID}');\">{Folder.Name}</div>";
	TTCheckboxList.prototype.folderFormatString += "</div>\n";

	TTCheckboxList.prototype.folderFormatString += "<div id=\"{Folder.ID}-open\" class=\"folder\" style=\"display:none;\">";
	TTCheckboxList.prototype.folderFormatString += "	<div>";
	TTCheckboxList.prototype.folderFormatString += "		<div class=\"collapse\" onClick=\"TTCheckboxList_CloseFolder('{Folder.ID}');\"><code>-</code></div>";
	TTCheckboxList.prototype.folderFormatString += "		<div class=\"select_all_ckeckBox\"><input type=\"checkbox\" name=\"{Folder.ID}_folder\" id=\"{Folder.ID}_checkall_open\" onClick=\"{Name}.selectAllItems('open','{Folder.folderId}','{Folder.ID}');\"></div>";
	TTCheckboxList.prototype.folderFormatString += "		<div class=\"cbl_folder\" onClick=\"TTCheckboxList_CloseFolder('{Folder.ID}');\">{Folder.Name}</div>";
	TTCheckboxList.prototype.folderFormatString += "	</div>";
	TTCheckboxList.prototype.folderFormatString += "	{Folder.Items}";
	TTCheckboxList.prototype.folderFormatString += "	</div>";
	
	//TTCheckboxList.prototype.folderFormatString = "<div id=\"{Folder.ID}-close\" class=\"folder\"  onClick=\"TTCheckboxList_OpenFolder('{Folder.ID}');\"><div class=\"expand\"><code>+</code></div><div class=\"select_all_ckeckBox\">{Checkbox}</div><div class=\"cbl_folder\">{Folder.Name}</div></div>\n<div id=\"{Folder.ID}-open\" class=\"folder\" style=\"display:none;\"><div onClick=\"TTCheckboxList_CloseFolder('{Folder.ID}');\"><div class=\"collapse\"><code>-</code></div><div class=\"select_all_ckeckBox\">{Checkbox}</div><div class=\"cbl_item\">{Folder.Name}</div></div>{Folder.Items}</div>";
	// Defined the layout of the item in the TTCheckboxList control.
	TTCheckboxList.prototype.itemFormatString = "<div class=\"item\">{Checkbox}<div class=\"cbl_item\"><label for=\"{Item.ID}\">{Item.Name}</label></div></div>\n";
	
	// Specifies whether we want to open a folder whenever we select an item.
	TTCheckboxList.prototype.openFolderOnSelect = false;
		
	// Specifies whether we want to render the top-level items before the folders.
	TTCheckboxList.prototype.renderItemsFirst = false;
	
	// Specifies whether we want to do the fix for IE.
	// When the first folder is opened at startup, we do not want to do this fix.
	TTCheckboxList.prototype.doMsieFix = true;

	// Specifies the folder to render. If this property is set to a reference to a folder,
	// the control will render only this folder instead of all folders:
	TTCheckboxList.prototype.folderToRender = null;

	// The zero-based index or name of the Form which contains the control:
	TTCheckboxList.prototype.formID = 0;

	// Renders a specified folder:
	TTCheckboxList.prototype.renderFolder = function( folder, html ) {
		if ( this.folderFormatFunction == null ) {
			var code = "html.push(\"" + this.folderFormatString.replace( /"/g, "\\\"" ).replace( /\n/g, "\\n" ) + "\");";
			code = code.replace( /\{Name\}/g, "\");html.push(\"" + this.name + "\");html.push(\"" );
			code = code.replace( /\{Folder\.folderId\}/g, "\");html.push(folder.folderId);html.push(\"" );
			code = code.replace( /\{Folder\.ID\}/g, "\");html.push(folder.id);html.push(\"" );
			code = code.replace( /\{Folder\.Name\}/g, "\");html.push(folder.name);html.push(\"" );
			code = code.replace( /\{Folder\.Items\}/g, "\");for(var i=0;i<folder.items.length;i++)this.renderItem(folder.items[i],html);html.push(\"" );
			this.folderFormatFunction = new Function( "folder", "html", code );
		}

		// Do not render empty folders:
		if ( folder.items.length > 0 ) {
			this.folderFormatFunction( folder, html );
		}
	}

	// Renders a specified item:
	TTCheckboxList.prototype.renderItem = function( item, html ) {
		if ( this.itemFormatFunction == null ) {
			var code = "html.push(\"" + this.itemFormatString.replace( /"/g, "\\\"" ).replace( /\n/g, "\\n" ) + "\");";
			code = code.replace( /\{Checkbox}/g, "<input type=\\\"checkbox\\\" name=\\\"{Name}_values[]\\\" value=\\\"{Item.Value}\\\" id=\\\"{Item.ID}\\\"{Disabled}>" );
			code = code.replace( /\{Name\}/g, "\");html.push(\"" + this.name + "\");html.push(\"" );
			code = code.replace( /\{Item\.ID\}/g, "\");html.push(item.id);html.push(\"" );
			code = code.replace( /\{Item\.Name\}/g, "\");html.push(item.name);html.push(\"" );
			code = code.replace( /\{Item\.Value\}/g, "\");html.push(item.value);html.push(\"" );
			code = code.replace( /\{Disabled\}/g, "\");html.push( this.disabled ? \" disabled='Yes'\" : \"\" );html.push(\"" );
			this.itemFormatFunction = new Function( "item", "html", code );
		}

		this.itemFormatFunction( item, html );
	}
	
	// Gets a list of all items whose name contains the specified text.
	TTCheckboxList.prototype.find = function( text ) {
		var result = new Array();
		result.names = new Object();
		result.duplicates = new Object();
		var re = new RegExp( "\\b" + text, "ig" );
		
		for ( var i = 0; i < this.folders.length; i++ ) {
			var folder = this.folders[ i ];

			for ( var j = 0; j < folder.items.length; j++ ) {
				var item = folder.items[ j ];
				
				if ( item.name.match( re ) ) {
					result.push( item );
					result.duplicates[ item.name ] = ( result.names[ item.name ] == true );
					result.names[ item.name ] = true;
				}
			}
		}

		for ( var j = 0; j < this.items.length; j++ ) {
			var item = this.items[ j ];
				
			if ( item.name.match( re ) ) {
				result.push( item );
				result.duplicates[ item.name ] = ( result.names[ item.name ] == true );
				result.names[ item.name ] = true;
			}
		}
		
		// The result will be sorted alphabetically by item name.
		// Duplicate items will be sorted by folder name.
		result.sort( function( a, b ) { 
			if ( a.name > b.name ) return 1;
			if ( a.name < b.name ) return -1;
			if ( a.folder.name > b.folder.name ) return 1;
			if ( a.folder.name < b.folder.name ) return -1;
			return 0;
		} );
		
		return result;
	}
	
/******************************************************************************
 * TTCheckboxList_Folder
 *****************************************************************************/

	// Initializes a new instance of the TTCheckboxList_Folder class.
	function TTCheckboxList_Folder( checkBoxListName, id, folder ) {
		this.checkBoxListName = checkBoxListName;
		this.folderId = id;
		this.id = checkBoxListName+"-"+id;
		this.name = folder[ 0 ];
		this.items = new Array();
		for ( var i = 0; i < folder[ 1 ].length; i++ ) if ( folder[ 1 ][ i ] != null ) this.items.push( new TTCheckboxList_Item( checkBoxListName, this, this.nextItemID(), folder[ 1 ][ i ] ) );
		if ( folder.length > 2 ) this.folderInfo = folder[ 2 ]; 
	
	}
	
	TTCheckboxList_Folder.prototype.nextItemID = function() {
		if ( this.itemCnt == null ) this.itemCnt = 0;
		return this.id + "-" + this.itemCnt++;
	}
	
	TTCheckboxList_Folder.prototype.isOpened = function() {
		var element = document.getElementById( this.id + "-open" );
		return ( element != null && element.style.display == "" );
	}

	// Copies the array of folder initializers and returns the copy:
	TTCheckboxList_Folder.copy = function( folders ) {
		var result = new Array();

		for ( var i = 0; i < folders.length; i++ ) {
			var newFolder = [ folders[ i ][ 0 ], TTCheckboxList_Item.copy( folders[ i ][ 1 ] ) ];
			if ( folders[ i ].length > 2 ) newFolder.push( folders[ i ][ 2 ] );
			result.push( newFolder );
		}

		return result;
	}
	
	// Adds folders from the "foldersToAdd" list to the "existingFolders" list.
	// We assume the folders are ordered by name.
	TTCheckboxList_Folder.add = function( existingFolders, foldersToAdd ) {
		for ( var i = 0; i < foldersToAdd.length; i++ ) {
			// The name and value of the folder to insert:
			var folderName  = foldersToAdd[ i ][ 0 ];

			// The existing or newly created folder:
			var folder = null;
			
			for ( var j = 0; j < existingFolders.length; j++ ) {
				// If the folder already exists in the folder, then do add items to this folder.
				if ( existingFolders[ j ][ 0 ].toLowerCase() == folderName.toLowerCase() ) {
					folder = existingFolders[ j ];
					TTCheckboxList_Item.add( existingFolders[ j ][ 1 ], foldersToAdd[ i ][ 1 ] )
					break;
				}
	
				// Otherwise insert the new folder, but make sure to preserve.
				// the alphabetical order of the folder names.
				if ( existingFolders[ j ][ 0 ].toLowerCase() > folderName.toLowerCase() ) {
					folder = [ folderName, TTCheckboxList_Item.copy( foldersToAdd[ i ][ 1 ] ) ];
					existingFolders.splice( j, 0, folder );
					break;
				}
			}
				
			// If we have not found the folder in the "existingFolders" list nor found
			// a right place to insert new folder, then append the new folder
			// at the end of the "existingFolders" list
			if ( folder == null ) {
				var newFolder = [ folderName, TTCheckboxList_Item.copy( foldersToAdd[ i ][ 1 ] ) ];
				if ( foldersToAdd[ i ].length > 2 ) newFolder.push( foldersToAdd[ i ][ 2 ] );
				existingFolders.push( newFolder );
			}
		}
	}

	// Removes folders from the "foldersToRemove" list from the "existingFolders" list.
	// We assume the folders are ordered by name.
	TTCheckboxList_Folder.remove = function( existingFolders, foldersToRemove ) {
		for ( var i = 0; i < foldersToRemove.length; i++ ) {
			// The name of the folder to remove:
			var folderName  = foldersToRemove[ i ][ 0 ];
			
			for ( var j = 0; j < existingFolders.length; j++ ) {
				// The folders to remove does not exist in the "existingFolders" list:
				if ( existingFolders[ j ][ 0 ].toLowerCase() > folderName.toLowerCase() ) break;
				
				if ( existingFolders[ j ][ 0 ].toLowerCase() == folderName.toLowerCase() ) {
					// Remove items from the folder
					TTCheckboxList_Item.remove( existingFolders[ j ][ 1 ], foldersToRemove[ i ][ 1 ] );

					// If there are no more items left then remove the folder itself:
					if ( existingFolders[ j ][ 1 ].length == 0 ) existingFolders.splice( j, 1 );
					break;
				}
			}
		}
	}

/******************************************************************************
 * TTCheckboxList_Item
 *****************************************************************************/
 
	// Initializes a new instance of the TTCheckboxList_Item class.
	function TTCheckboxList_Item( checkBoxListName, folder, id, item ) {
		this.checkBoxListName = checkBoxListName;
		this.folder = folder;
		this.id = id;
		this.value = item[ 0 ];
		this.name = item[ 1 ];
		if ( item.length > 2 ) this.itemInfo = item[ 2 ]; 
	}
	
	// Gets the reference to the TTCheckboxList control which owns the current item:
	TTCheckboxList_Item.prototype.getCheckBoxList = function() { return window[ this.checkBoxListName ]; }

	// Tests whether the item is selected.
	TTCheckboxList_Item.prototype.isSelected = function() {
		if ( this.checkBox == null ) return false;
		return this.checkBox.checked;
	}

	// Selects the current item.
	TTCheckboxList_Item.prototype.select = function( value ) {
		if ( this.checkBox != null && value != this.isSelected() ) {
			this.checkBox.checked = value;
			if ( !this.getCheckBoxList().onItemSelected( this ) ){ 
				this.checkBox.checked = false;
			}
		}
	}

	// Copies the array of item initializers and returns the copy:
	TTCheckboxList_Item.copy = function( items ) {
		var result = new Array();

		for ( var i = 0; i < items.length; i++ ) {
			if (items[i]!= undefined)
			{
				var newItem = [ items[ i ][ 0 ], items[ i ][ 1 ] ];
				if ( items[ i ].length > 2 ) newItem.push( items[ i ][ 2 ] );
				result.push( newItem );
			}
		}

		return result;
	}

	// Adds items from the "itemsToAdd" list to the "existingItems" list.
	// We assume the items are ordered by name.
	TTCheckboxList_Item.add = function( existingItems, itemsToAdd ) {
		for ( var i = 0; i < itemsToAdd.length; i++ ) {
			// The name and value of the item to insert:
			var itemValue = itemsToAdd[ i ][ 0 ];
			var itemName  = itemsToAdd[ i ][ 1 ];

			// The existing or newly created item:
			var item = null;
			
			for ( var j = 0; j < existingItems.length; j++ ) {
				// If the item already exists in the folder, then do nothing.
				if ( existingItems[ j ][ 1 ].toLowerCase() == itemName.toLowerCase() ) {
					item = existingItems[ j ];
					break;
				}
	
				// Otherwise insert the new item, but make sure to preserve.
				// the alphabetical order of the item names.
				if ( existingItems[ j ][ 1 ].toLowerCase() > itemName.toLowerCase() ) {
					item = [ itemValue, itemName ];
					existingItems.splice( j, 0, item );
					break;
				}
			}
				
			// If we have not found the item in the "existingItems" list nor found
			// a right place to insert new item, then append the new item
			// at the end of the "existingItems" list
			if ( item == null ) {
				var newItem = [ itemValue, itemName ];
				if ( itemsToAdd[ i ].length > 2 ) newItem.push( itemsToAdd[ i ][ 2 ] );
				existingItems.push( newItem );
			}
		}
	}

	// Removes items from the "itemsToRemove" list from the "existingItems" list.
	// We assume the items are ordered by name.
	TTCheckboxList_Item.remove = function( existingItems, itemsToRemove ) {
		for ( var i = 0; i < itemsToRemove.length; i++ ) {
			// The name of the item to remove:
			var itemName  = itemsToRemove[ i ][ 1 ];
			
			for ( var j = 0; j < existingItems.length; j++ ) {
				// The item to remove does not exist in the "existingItems" list:
				if ( existingItems[ j ][ 1 ] > itemName ) break;
				
				// If we found the item, we will remove it from the "existingItems" list.
				if ( existingItems[ j ][ 1 ] == itemName ) {
					existingItems.splice( j, 1 );
					break;
				}
			}
		}
	}

/******************************************************************************
 * TTCheckboxList_Selection
 *****************************************************************************/
 
	// Initializes a new instance of the TTCheckboxList_Selection class.
	function TTCheckboxList_Selection() {
		this.folders = new Array();
		this.items = new Array();
		this.itemCount = 0;
	}

/******************************************************************************
 * TTCheckboxList_TallyBox
 *****************************************************************************/
 
	// Initializes a new instance of the TTCheckboxList_TallyBox class.
	function TTCheckboxList_TallyBox( checkBoxListName ) {
		this.checkBoxListName = checkBoxListName;
	}

	// Defines the layout of the folders within the TallyBox.	
	TTCheckboxList_TallyBox.prototype.folderFormatString = "<div class=\"folder\">\n<div class=\"header\">{Folder.Name}</div>\n{Folder.Items}</div>";
	
	// Defines the layout of the items within the TallyBox.
	TTCheckboxList_TallyBox.prototype.itemFormatString = "<div class=\"item\"><div class=\"remove\"><a href=\"javascript:{Name}.select('{Item.Value}',false);\">X</a></div>{Item.Name}</div>\n";
	
	// Gets the reference to the TTCheckboxList object which owns the current TallyBox:
	TTCheckboxList_TallyBox.prototype.getCheckBoxList = function() { return window[ this.checkBoxListName ]; }

	// Renders a specified folder:
	TTCheckboxList_TallyBox.prototype.renderFolder = function( folder, html ) {
		if ( this.folderFormatFunction == null ) {
			var code = "var code=new Array();code.push(\"" + this.folderFormatString.replace( /"/g, "\\\"" ).replace( /\n/g, "\\n" ) + "\");html.push(code.join(\"\"));";
			code = code.replace( /\{Name\}/g, "\");code.push(\"" + this.checkBoxListName + "\");code.push(\"" );
			code = code.replace( /\{Folder\.Name\}/g, "\");code.push(folder.name);code.push(\"" );
			code = code.replace( /\{Folder\.Items\}/g, "\");for(var i=0;i<folder.items.length;i++)this.renderItem(folder.items[i],code);code.push(\"" );
			this.folderFormatFunction = new Function( "folder", "html", code );
		}

		this.folderFormatFunction( folder, html );
	}

	// Renders a specified item:
	TTCheckboxList_TallyBox.prototype.renderItem = function( item, html ) {
		if ( this.itemFormatFunction == null ) {
			var code = "var code=new Array();code.push(\"" + this.itemFormatString.replace( /"/g, "\\\"" ).replace( /\n/g, "\\n" ) + "\");html.push(code.join(\"\"));";
			code = code.replace( /\{Name\}/g, "\");code.push(\"" + this.checkBoxListName + "\");code.push(\"" );
			code = code.replace( /\{Item\.Name\}/g, "\");code.push(item.name);code.push(\"" );
			code = code.replace( /\{Item\.Value\}/g, "\");code.push(item.value);code.push(\"" );		
			
			this.itemFormatFunction = new Function( "item", "html", code );
		}
		this.itemFormatFunction( item, html );
	}

	// Renders the tally box itself.
	TTCheckboxList_TallyBox.prototype.render = function( id ) {
		var html = new Array();
		var selection = this.getCheckBoxList().getSelection();

		for ( var i = 0; i < selection.folders.length; i++ ) this.renderFolder( selection.folders[ i ], html );
		for ( var i = 0; i < selection.items.length; i++ ) this.renderItem( selection.items[ i ], html );

		var element = document.getElementById( id );
		element.innerHTML = html.join( "\n" );
	}

/******************************************************************************
 * TTCheckboxList_QuickFind
 *****************************************************************************/
 
	// Initializes a new instance of the TTCheckboxList_QuickFind class.
	function TTCheckboxList_QuickFind( id, checkBoxListName ) {
		this.id = id;
		this.checkBoxListName = checkBoxListName;
	}
	
	// Max number of results returned by the find() method;
	TTCheckboxList_QuickFind.prototype.maxFindResults = 10;
	
	// Gets the reference to the TTCheckboxList control which owns the current TallyBox:
	TTCheckboxList_QuickFind.prototype.getCheckBoxList = function() {	return window[ this.checkBoxListName ]; }
	
	// Gets the reference to the hidden field containing the value of the selected item.
	TTCheckboxList_QuickFind.prototype.getHiddenField = function() { return window[ "hdn" + this.id ]; }
	
	// Gets the reference to the text box containing the name of the selected item.
	TTCheckboxList_QuickFind.prototype.getTextBox = function() { return window[ "txt" + this.id ]; }
	
	// Gets the reference to the button.
	TTCheckboxList_QuickFind.prototype.getButton = function() { return window[ "btn" + this.id ]; }
	
	// Gets the reference to the menu containing all matching items.
	TTCheckboxList_QuickFind.prototype.getMenu = function() { return window[ "mnu" + this.id ]; }
	
	// Attaches event handlers:
	TTCheckboxList_QuickFind.prototype.attachEvents = function() {
		
		// If the user changes focus and clicks anywhere else on the page, the drop-down list should disappear
		if ( document.clickHandlers == null ) {
			document.clickHandlers = new Array();
			if ( document.onclick != null ) document.clickHandlers.push( document.onclick );
			document.onclick = function() { for ( var i = 0; i < document.clickHandlers.length; i++ ) document.clickHandlers[ i ](); }	
		}
		
		document.clickHandlers.push( new Function( this.getMenu().id + ".close();" ) );
				
		// Menu:
		this.getMenu().quickFind = this;
		this.getMenu().open = function()  { document.getElementById( this.id ).style.display = ""; }
		this.getMenu().close = function() { document.getElementById( this.id ).style.display = "none"; selectedItemId=""; selectedIndex = -1;}
		
		// TextBox:
		this.getTextBox().quickFind = this;
		var updateMenu = function( e ) {
		
			if ( this.value != null && this.value.length >= 3 ){
				this.quickFind.render();
				this.quickFind.navigation( e );					
			}
			else this.quickFind.getMenu().close();
			
			return true;			
		}
		
		var selectQuickFindItem = function( e ){
			var keyCode = ( e != null ) ? e.keyCode : window.event.keyCode;

			switch (keyCode)
			{
				case 9:		//Tab key							
					TTCheckboxList.prototype.SelectDropDownItem();				
					break;
			}
		}
		
		this.getTextBox().onkeyup = updateMenu;
		this.getTextBox().onkeydown = selectQuickFindItem;
		this.getTextBox().onfocus = updateMenu;
		
		// Button:
		this.getButton().quickFind = this;
		this.getButton().onclick = function() {
			this.quickFind.getCheckBoxList().select( this.quickFind.getHiddenField().value, true );
			this.quickFind.getHiddenField().value = "";
			this.quickFind.getTextBox().value = "";
			this.quickFind.getMenu().close();
			this.disabled = true;
		}
	}
	
	var renderedItemsArray = new Array();
	var selectedItemId = "";
	var selectedIndex = -1;
	
	TTCheckboxList_QuickFind.prototype.navigation = function( e ){
		var code = ( e != null ) ? e.keyCode : window.event.keyCode;				

		switch (code)
		{
			case 38:								
				if(renderedItemsArray.length >0 && selectedIndex-1>=0 && selectedIndex-1<=renderedItemsArray.length-1)
				{
					selectedIndex--;
					TTCheckboxList.prototype.SetItemHighlight(renderedItemsArray[selectedIndex][0]);
				}	
				break;			
				
			case 40:				
				if(renderedItemsArray.length >0 && (selectedIndex+1 < renderedItemsArray.length))
				{	
					selectedIndex++;
					TTCheckboxList.prototype.SetItemHighlight(renderedItemsArray[selectedIndex][0]);
				}		
				break;
				
			case 13:	//Enter key							
				TTCheckboxList.prototype.SelectDropDownItem();
				this.getButton().focus();
				break;
				
			default:
		}
	} 
	
	TTCheckboxList.prototype.SetItemHighlight = function(id){
		
		//Unselect already selected item before selecting new one.
		if(selectedItemId!="" && selectedItemId!=null && document.getElementById(selectedItemId))
		{
			document.getElementById(selectedItemId).className = 'Item';
		}	
		
		//Select the item.	
		document.getElementById(id).className = 'Item MouseOver';
		selectedItemId = id;		
	}	
	
	TTCheckboxList.prototype.SelectDropDownItem = function(id){
		
		var index = selectedIndex;
		
		var id = renderedItemsArray[index][1];
		var item = renderedItemsArray[index][2];
		
		document.getElementById("txt" + id).value = item.name;	//.replace( /'/g, "\\'" );
		document.getElementById("hdn" + id).value = item.value;
		document.getElementById("btn" + id).disabled = false;
		document.getElementById("mnu" + id).close();				
	}
	
	// Renders the menu with the matching items.	
	TTCheckboxList_QuickFind.prototype.render = function() {
	
		//clear array before adding items
		renderedItemsArray = new Array();
				
		if ( this.itemFormatFunction == null ) {
			this.itemFormatFunction = function( item, re, isDuplicate, html ) {
						
				var id = "mnu" + this.id + "_" + item.value;
				var code = new Array();
				code.push( "<div " );
				
				if(selectedItemId==id)
					code.push( "class=\"Item MouseOver\" id=\"" + id + "\" " );
				else
					code.push( "class=\"Item\" id=\"" + id + "\" " );
			
				code.push( "onclick=\"txt" + this.id + ".value=" );
				code.push( "'" + item.name.replace( /'/g, "\\'" ) + "';" );
				code.push( "hdn" + this.id + ".value='" + item.value + "';" );
				code.push( "btn" + this.id + ".disabled=false;" );
				code.push( "mnu" + this.id + ".close();return false;\" " );
				code.push( "onmouseover=\"TTCheckboxList.prototype.SetItemHighlight('" + id + "');\" " );
				code.push( "onmouseout=\"document.getElementById('" + id + "').className='Item';selectedIndex=-1;selectedItemId='';\">" );
				code.push( item.name.replace( re, "<b>$1</b>" ) );
				if ( isDuplicate && item.folder != null ) code.push( " (" + item.folder.name + ")" );
				code.push( "</div>" );
				html.push( code.join( "" ) );
				
				renderedItemsArray.push([id, this.id, item]);
								
			}
		}
			
		var menu = this.getMenu();
		var text = this.getTextBox().value;
		var items = this.getCheckBoxList().find( text );
		var re = new RegExp( "\\b(" + text + ")", "gi" );
		
		if ( items.length > 0 ) {
			var html = new Array();
			
			var cnt = 0;
			for ( var i = 0; ( i < items.length && cnt < this.maxFindResults ); i++ ) {
				var item = items[ i ];
				if ( item.isSelected() ) continue;
				cnt++;
				this.itemFormatFunction( item, re, items.duplicates[ item.name ], html );
			}
			
			if ( html.length > 0 ) {
				menu.open();
				menu.innerHTML = html.join( "\n" );
			}
			
			else {
				menu.close();
			}
			
			if ( items.length == 1 ) {
				this.getHiddenField().value = items[ 0 ].value;
				this.getButton().disabled = false;
			}
			
			else {
				this.getHiddenField().value = "";
				this.getButton().disabled = true;
			}
		}
		
		else {
			menu.close();
			this.getButton().disabled = true;
		}
		
		
		//Set first item automatically highlighted when the list appears.
		
		if(selectedIndex<=0 && renderedItemsArray.length >0)
		{
			var firstItemId = renderedItemsArray[0][0];
			TTCheckboxList.prototype.SetItemHighlight(firstItemId);
			selectedItemId = firstItemId;
			selectedIndex = 0;
		}
		
	}

/******************************************************************************
 * TTCheckboxList_SelectionValidator
 *****************************************************************************/
 
// This validator checks whether the user did not select more items or folders than allowed.
function TTCheckboxList_SelectionValidator( errorMessage, maxItems, maxFolders, maxItemsInFolder ) {
	this.errorMessage = errorMessage;
	this.maxItems = maxItems != null ? maxItems : 0;
	this.maxFolders = maxFolders != null ? maxFolders : 0;
	this.maxItemsInFolder = maxItemsInFolder != null ? maxItemsInFolder : 0;
}

TTCheckboxList_SelectionValidator.prototype.validate = function( checkBoxList ) {
	var result = true;
	var selection = checkBoxList.getSelection();
	
	if ( this.maxItems > 0 ) result = result && ( selection.itemCount <= this.maxItems );
	if ( result && this.maxFolders > 0 ) result = result && ( selection.folders.length <= this.maxFolders );
	
	if ( result && this.maxItemsInFolder > 0 ) {
		for ( var i = 0; i < selection.folders.length; i++ ) {
			result = result && ( selection.folders[ i ].items.length <= this.maxItemsInFolder );
			if ( !result ) break;
		}
	}
	
	return result;
}


