
(function () {
	var methods = {
		indexOf: function (obj, fromIndex) {
			if (fromIndex == null) {
				fromIndex = 0;
			} else if (fromIndex < 0) {
				fromIndex = Math.max(0, this.length + fromIndex);
			}
			for (var i = fromIndex; i < this.length; i++) {
				if (this[i] === obj)
					return i;
			}
			return -1;
		},
		
		lastIndexOf: function (obj, fromIndex) {
			if (fromIndex == null) {
				fromIndex = this.length - 1;
			} else if (fromIndex < 0) {
				fromIndex = Math.max(0, this.length + fromIndex);
			}
			for (var i = fromIndex; i >= 0; i--) {
				if (this[i] === obj)
					return i;
			}
			return -1;
		},
		
		forEach: function (f, obj) {
			var l = this.length;	// must be fixed during loop... see docs
			for (var i = 0; i < l; i++) {
				f.call(obj, this[i], i, this);
			}
		},
		
		filter: function (f, obj) {
			var l = this.length;	// must be fixed during loop... see docs
			var res = [];
			for (var i = 0; i < l; i++) {
				if (f.call(obj, this[i], i, this)) {
					res.push(this[i]);
				}
			}
			return res;
		},
		
		map: function (f, obj) {
			var l = this.length;	// must be fixed during loop... see docs
			var res = [];
			for (var i = 0; i < l; i++) {
				res.push(f.call(obj, this[i], i, this));
			}
			return res;
		},
		
		some: function (f, obj) {
			var l = this.length;	// must be fixed during loop... see docs
			for (var i = 0; i < l; i++) {
				if (f.call(obj, this[i], i, this)) {
					return true;
				}
			}
			return false;
		},
		
		every: function (f, obj) {
			var l = this.length;	// must be fixed during loop... see docs
			for (var i = 0; i < l; i++) {
				if (!f.call(obj, this[i], i, this)) {
					return false;
				}
			}
			return true;
		}
	};
	
	for (var i in methods) {
		if (!Array.prototype[i]) Array.prototype[i] = methods[i];
	}
})();

// Mozilla's Array Generics
['concat', 'every', 'filter', 'forEach', 'indexOf', 'join', 'lastIndexOf', 'map', 'some', 'slice'].forEach(function(func) {
	if (!Array[func]) Array[func] = function (object) {
		return this.prototype[func].apply(object, Array.prototype.slice.call(arguments, 1));
	}
});
