
	//*************************************************************************************
	//********************************* J2H_CollectionData ********************************
	//*************************************************************************************
	function J2H_CollectionData( key, value ) {
		this.key = key;
		this.value = value;
		this.name = "CollectionData";
		return this;
	}
	
	
	//*************************************************************************************
	//********************************* J2H_Collection ************************************
	//*************************************************************************************
	function J2H_Collection( ) {
		this.count = 0;
		this.items = new Array( );
		this.set = _J2H_Collection_addItem;
		this.get = _J2H_Collection_getItem;
		this.getByKey = __J2H_Collection_getByKey;
		this.getByPos = __J2H_Collection_getByPos;
		this.reset = _J2H_Collection_reset;
		this.remove = _J2H_Collection_remove;
		this.overwriteMode = true;
		//this.removeItem = _J2H_Collection_removeItem
		//this.compactItems = __J2H_Collection_compactItems
		//this.setItem = _J2H_Collection_setItem;
		//this.currentItem = _J2H_Collection_currentItem;
	}
	
	function _J2H_Collection_addItem( key, value ) {
		var cd, element;
		element = this.get( key );
		if ( element != null ) {
			if ( this.overwriteMode == true ) {
				element.key = key;
				element.value = value;
			} else if ( this.overwriteMode == false ) {
				element.value = element.value + " " + value;
			}
			return;
		} else {
			cd = new J2H_CollectionData(key,value);	
			this.items[this.count] = cd;
			this.count++;
		}
	}
	
	function __J2H_Collection_getByKey( key ) {
		var i, found, element;
		found = false;
		element = null;
		for (i = 0; i < this.count && ! found; i++ ) {
			if ( typeof( this.items[i] ) != "undefined" ) {
				if ( this.items[i].key == key ) {
					found = true;
					element = this.items[i];
				}
			}
		}
		if ( found ) {
			return element;
		} else {
			return null;
		}
	}
	
	function __J2H_Collection_getByPos( index ) {	
		if ( typeof( this.items[index] ) != "undefined" ) {
			return this.items[index];
		} else {
			return null;
		}
	}	
	
	function _J2H_Collection_getItem( val ) {
		switch( typeof(val) ) {
			case "string": // assume una ricerca per chiave
				return this.getByKey( val );
				break;
			case "number":
				return this.getByPos( val );
				break;
			case "undefined":
				return null;
				break;
		}
	}
	
	function _J2H_Collection_remove( val ) {
		var index;
		if ( typeof(val) == "string" ) {
			for ( index = 0; index < this.count && this.items[index].key != val; index ++ ) {
				;
			}
		}
		if ( index < 0 || index >= this.count ) {
			error( "J2H_Collection.remove : indice fuori limiti o elemento inesistente." );
			return;
		}
		// cancella l'elemento		
		delete this.items[index];
		
		// compatta l'array spostando indietro di una posizione tutti gli elementi
		// successivi a quello cancellato.
		while( index < this.count ) {
			this.items[index] = this.items[index+1];
			index++;
		}
		
		// cancella lo slot vuoto rimasto alla fine dell'array. In un altro linguaggio
		// sarebbe stato necessario controllare che questo ultimo elemento non 
		// corrispondesse a quello già cancellato onde evitare una doppia cancellazione
		// con risultati imprevisti. Quì il linguaggio si fà carico di tutto, ed è 
		// possibile cancellare un elemento già eliminato risparmiando il controllo.
		delete this[index];
		
		// c'è un elemento in meno nell'array, decrementiamo il contatore degli elementi
		this.count--;
	}	
	
	function _J2H_Collection_reset( ) {
		var i;
		for ( i = 0; i < this.count; i++ ) {
			delete this.items[i];
		}
		this.count = 0;
	}
	
	

	function HLink( url, linktext ) {
		// variabili private
		var _href = url;
		var _text = linktext;
		var _anchor = "";
		var _target = "";
		var _title = "";
		var _parameters = new J2H_Collection( ); 
		var _handlers = new J2H_Collection( );


		this.title = function( ) {
			if ( arguments.length == 0 ) {
				return _title;
			} else if ( arguments.length == 1 ) {
				_title = arguments[0];
			}
		}
		
		this.text = function( ) {
			if ( arguments.length == 0 ) {
				return _text;
			} else if ( arguments.length == 1 ) {
				_text = arguments[0];
			}
		}
		
		this.target = function( ) {
			if ( arguments.length == 0 ) {
				return _target;
			} else if ( arguments.length == 1 ) {
				_target = arguments[0];
			}
		}


		this.href = function( ) {
			if ( arguments.length == 0 ) {
				return _href;
			} else if ( arguments.length == 1 ) {
				_href = arguments[0];
			}
		}
		
		this.anchor = function( ) {
			if ( arguments.length == 0 ) {
				return _anchor;
			} else {
				_anchor = arguments[0];
			}
		}
			
		this.handlers = function( ) {	
			/***************************************************************************** 
			se non è stato passato alcun parametro restituisce un riferimento all'oggetto
			_parameter interno, in modo da dare pieno accesso alle sue proprietà ed ai
			suoi metodi
			*****************************************************************************/
			if ( arguments.length == 0 ) { 
				return _handlers; 
			/****************************************************************************
			al metodo è stato passato un parametro, la chiave con cui recuperare 
			l'oggetto J2H_CollectionData memorizzato nella collection interna.
				****************************************************************************/
			} else if ( arguments.length == 1 ) {
				return _handlers.get(key);
			/****************************************************************************
			il metodo è stato richiamato con 2 parametri, deve aggiungere o sostituire un 
			elemento nella collection interna.
			*****************************************************************************/
			} else if ( arguments.length == 2 ) {
				_handlers.set(arguments[0],arguments[1]);
			}
		}	
		
		
		this.parameters = function( ) {
			/***************************************************************************** 
			se non è stato passato alcun parametro restituisce un riferimento all'oggetto
			_parameter interno, in modo da dare pieno accesso alle sue proprietà ed ai
			suoi metodi
			*****************************************************************************/
			if ( arguments.length == 0 ) { 
				return _parameters; 
			/****************************************************************************
			al metodo è stato passato un parametro, la chiave con cui recuperare 
			l'oggetto J2H_CollectionData memorizzato nella collection interna.
				****************************************************************************/
			} else if ( arguments.length == 1 ) {
				return _parameters.get(key);
			/****************************************************************************
			il metodo è stato richiamato con 2 parametri, deve aggiungere o sostituire un 
			elemento nella collection interna.
			*****************************************************************************/
			} else if ( arguments.length == 2 ) {
				_parameters.set(arguments[0],arguments[1]);
			}
		}	
		
		this.get = function( ) {
			var htmltext = "";
			var pars = _getParameterString( );
			var hnd = _getHandlersString( );
			
			htmltext += "<a href=\"" + _href;
			if ( pars != "" ) {
				htmltext += "?" + pars + "\"";
			} else {
				htmltext += "\"";
			}
			
			if ( hnd != "" ) {
				htmltext += " " + hnd;
			}
			
			if ( _title != "" ) {
				htmltext += " title=\"" + _title + "\"";
			}
			
			if ( _target != "" ) {
				htmltext += " target=\"" + _target + "\"";
			}
			
			htmltext += ">" + _text + "</a>";
			return htmltext;
		}
		
		
		function _getParameterString( ) {
			var count, i, pars, cd;
			pars = "";
			count = _parameters.count;
			for( i = 0; i < count; i++ ) {
				cd = _parameters.get(i);
				pars = pars + cd.key + "=" + cd.value;
				if ( i < count-1 ) {
					pars = pars + "&";
				}
			}
			// aggiunge un eventuale anchor alla fine dell'url
			if ( _anchor != "" ) {
				pars += "#" + _anchor;
			}
			return pars;
		}
		
		function _getHandlersString( ) {
			var count, i, htmltext, cd;
			htmltext = "";
			count = _handlers.count;
			for( i = 0; i < count; i++ ) {
				cd = _handlers.get(i);
				htmltext += cd.key + "=\"" + cd.value + "\"";
				htmltext += " ";
			}
			return htmltext;
		}
		
		
		function _setAttrib( obj ) {
			var pars = _doParameterString( );
 			if ( pars != "" ) {
				obj.ref( ).attrib("href", _href + "?" + pars);
			} else { // se non ci sono parametri, questa funzione è stata chiamata dal metodo href
				obj.ref( ).attrib("href",_href);
			}
		}
	}	
	

