Object.prototype.clone = function()
{
	var deep = arguments.length > 0 ? arguments[0] : true;
	var copy = new this.constructor();
	for (var p in this)
		if (!deep)
			copy[p] = this[p];
		else if (typeof this[p] == "object")
			copy[p] = this[p].clone(deep);
		else
			copy[p] = this[p];
	return(copy);
};

Array.prototype.iterator = function()
{
	var i = 0;
	var self = this;
	var closure = 
	{
		next : function() { if (i == self.length) { throw StopIteration; } return(self[i++]); },
		prev : function() { if (i < 0) { throw StopIteration; } return(self[i--]); },
		first : function() { return(self[i = 0]); },
		last : function() { return(self[i = self.length - 1]); },
		eol : function() { return(i > (self.length - 1) || i < 0); }
	};
	return(closure);
};

Array.prototype.map = function(transformer)
{
	var orig = this;
	var result = [];
	var i;
	for (i=0; i<orig.length; i++)
	{
		if (typeof transformer == "function") { result.push(transformer(orig[i])); }
	}
	return(result);
};

Array.prototype.grep = function(filter)
{
	var orig = this;
	var result = [];
	var i;
	for (i=0; i<orig.length; i++)
	{
		if (typeof filter == "function") { filter(orig[i]) && result.push(orig[i]); }
		else if (filter instanceof RegExp) { filter.test(orig[i]) && result.push(orig[i]); }
	}
	return(result)
};

