/**
 * @class Constructor of the Hashtable object<br>
 * This is a mapped collection with keys and associated values<br>
 *
 * @return The created Hashtable object
 * @constructor
 */
function Hashtable(){

	/**
	 * Table with values and associated keys
	 * @type Array
	 */
	this.hashtable = new Array();



	/**
	 * Remove all entries in the hashtable
	 */
	this.clear = function(){
		this.hashtable = new Array();
	}



	/**
	 * Tests the key existance in the hashtable
	 *
	 * @param {Object} key Key to test
	 * @return {Boolean} True if key is in the hashtable, false else
	 */
	this.containsKey = function(key){
		var exists = false;
		for (var i in this.hashtable) {
			if (i == key && this.hashtable[i] != null) {
				exists = true;
				break;
			}
		}
		return exists;
	}



	/**
	 * Tests the value existance in the hashtable
	 *
	 * @param {Object} value Value to test
	 * @return {Boolean} True if value is in the hashtable, false else
	 */
	this.containsValue = function(value){
		var contains = false;
		if (value != null) {
			for (var i in this.hashtable) {
				if (this.hashtable[i] == value) {
					contains = true;
					break;
				}
			}
		}
		return contains;
	}



	/**
	 * Returns the mapped object for this key
	 *
	 * @param {Object} key Key of the desired value
	 * @return {Object} Object mapped to this key
	 */
	this.get = function(key){
		return this.hashtable[key];
	}



	/**
	 * Tests if hashtable is empty
	 *
	 * @return {Boolean} True if hashtable is empty, false else
	 */
	this.isEmpty = function(){
		return (parseInt(this.size()) == 0) ? true : false;
	}



	/**
	 * Returns all keys of the hashtable
	 *
	 * @return {Array} Array of keys elements
	 */
	this.keys = function(){
		var keys = new Array();
		for (var i in this.hashtable) {
			if (this.hashtable[i] != null)
				keys.push(i);
		}
		return keys;
	}



	/**
	 * Returns all values of the hashtable
	 *
	 * @return {Array} Array of values elements
	 */
	this.values = function(){
		var values = new Array();
		for (var i in this.hashtable) {
			if (this.hashtable[i] != null)
				values.push(this.hashtable[i]);
		}
		return values;
	}



	/**
	 * Add an object to the hashtable
	 *
	 * @param {Object} key Key for mapped object
	 * @param {Object} value Value for mapped object
	 */
	this.put = function(key, value){
		if (key == null || value == null)
			throw "NullPointerException {" + key + "},{" + value + "}";
		else
			this.hashtable[key] = value;
	}



	/**
	 * Remove an object from the hashtable
	 *
	 * @param {Object} key Key of the object to remove
	 * @return {Object} Value of the removed object
	 */
	this.remove = function(key){
		var rtn = this.hashtable[key];
		this.hashtable[key] = null;
		return rtn;
	}



	/**
	 * Returns size of the hashtable
	 *
	 * @return {Int} Size of the hashtable
	 */
	this.size = function(){
		var size = 0;
		for (var i in this.hashtable) {
			if (this.hashtable[i] != null)
			size ++;
		}
		return size;
	}



	/**
	 * Returns representative string for the hashtable
	 *
	 * @return {String} Representative string of the hashtable
	 */
	this.toString = function(){
		var result = "";
		for (var i in this.hashtable) {
			if (this.hashtable[i] != null)
				result += "{" + i + "},{" + this.hashtable[i] + "}\n";
		}
		return result;
	}
}