Array.prototype.remove = function(from, to) {
    var rest = this.slice((to || from) + 1 || this.length);
    this.length = from < 0 ? this.length + from : from;
    return this.push.apply(this, rest);
};

Date.prototype.clone = function () {
  return new Date(this.getTime());
}

String.prototype.pad = String.prototype.pad || function(len, chr, dir) {
    var str = this;
    len = (typeof len == 'number') ? len : 0;
    chr = (typeof chr == 'string') ? chr : ' ';
    dir = (/left|right|both/i).test(dir) ? dir : 'right';
    var repeat = function(c, l) { // inner "character" and "length"
        var repeat = '';
        while (repeat.length < l) {
            repeat += c;
        }
        return repeat.substr(0, l);
    }
    var diff = len - str.length;
    if (diff > 0) {
        switch (dir) {
            case 'left':
                str = '' + repeat(chr, diff) + str;
                break;
            case 'both':
                var half = repeat(chr, Math.ceil(diff / 2));
                str = (half + str + half).substr(1, len);
                break;
            default: // and "right"
                str = '' + str + repeat(chr, diff);
        }
    }
    return str;
};

Hash.prototype.without = function() {
    var values = $A(arguments);
	var retHash = $H();
    this.each(function(entry) {
		if(!values.include(entry.key))
			retHash.set(entry.key, entry.value);
    });
	return retHash;
};

Element.insertAfter = function(insert, element) {
	if (element.nextSibling) element.parentNode.insertBefore(insert, element.nextSibling);
	else element.parentNode.appendChild(insert);
};

// Fix exceptions thrown thrown when removing an element with no parent
Element._remove = Element.remove;
Element.remove = function(element) {
	element = $(element);
	if (element.parentNode)
		return Element._remove(element);
};
