Array.toArray = function (obj) {
	var arr = [];
	for (var i = 0; i < obj.length; i++) arr[i] = obj[i];
	return arr;
}

if (typeof Array.prototype.pop === 'undefined')
	Array.prototype.pop = function() {
		var b = this[this.length - 1];
		this.length--;
		return b;
	};

Function.prototype.bind = function (obj) {
	var method = this;
	var args = Array.toArray(arguments).slice(1);
	return function () {
		var newArgs = Array.toArray(arguments);
		return method.apply(obj, args.concat(newArgs));
	};
}

Function.prototype.bindEventListener = function (obj) {
	var method = this;
	var args = Array.toArray(arguments).slice(1);
	return function (event) { return method.apply(obj, event || window.event, args); };
}

var BrowserUtils = {
	toArray: function (obj) {
		var arr = [];
		for (var i = 0; i < obj.length; i++) arr[i] = obj[i];
		return arr;
	},

	addEvent: function(el, e, func) {
		if (!(el && e && func)) return;
		if (el.addEventListener) el.addEventListener(e, func, false);
		else if (el.attachEvent) el.attachEvent('on' + e, func);
	},

	hasClass: function(el, cls) {
		return (el.className && el.className.match(new RegExp("\\b" + cls + "\\b"))) ? true : false;
	},

	addClass: function(el, cls) {
		if (!this.hasClass(el, cls)) {
			el.className = el.className + (el.className ? ' ' : '') + cls;
			return true;
		}
		return false;
	},

	removeClass: function(el, cls) {
		if (this.hasClass(el, cls)) {
			el.className = (' ' + el.className + ' ').replace(' ' + cls + ' ', ' ').replace(/^ | $/, '');
			return true;
		}
		return false;
	},
	
	getElementsByClassName: (document.getElementsByClassName) ? function (className, tag, el) {
			var elements = (el || document).getElementsByClassName(className),
				nodeName = (tag) ? new RegExp("\\b" + tag + "\\b", "i") : null,
				returnElements = [],
				current;
			for(var i = 0, imax = elements.length; i < imax; i++){
				current = elements[i];
				if(!nodeName || nodeName.test(current.nodeName)) returnElements.push(current);
			}
			return returnElements;
		} : (document.evaluate) ? function (className, tag, el) {
			tag = tag || "*";
			el = el || document;
			var classes = className.split(" "),
				classesToCheck = "",
				xhtmlNamespace = "http://www.w3.org/1999/xhtml",
				namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
				returnElements = [],
				elements,
				node;
			for(var i = 0, imax = classes.length; i < imax; i++)
				classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[i] + " ')]";
			try {
				elements = document.evaluate(".//" + tag + classesToCheck, el, namespaceResolver, 0, null);
			} catch (e) {
				elements = document.evaluate(".//" + tag + classesToCheck, el, null, 0, null);
			}
			while ((node = elements.iterateNext())) returnElements[returnElements.length] = node;
			return returnElements;
		} : function (className, tag, el) {
			tag = tag || "*";
			el = el || document;
			var classes = className.split(" "),
				classesToCheck = [],
				elements = (tag === "*" && el.all)? el.all : el.getElementsByTagName(tag),
				current,
				returnElements = [],
				match;
			for(var i = 0, imax = classes.length; i < imax; i++)
				classesToCheck[classesToCheck.length] = new RegExp("(^|\\s)" + classes[i] + "(\\s|$)");
			for(var i = 0, imax = elements.length; i < imax; i++) {
				current = elements[i];
				match = false;
				for(var j = 0, jmax = classesToCheck.length; j < jmax; j++) {
					match = classesToCheck[j].test(current.className);
					if (!match) break;
				}
				if (match) returnElements[returnElements.length] = current;
			}
			return returnElements;
		},
	// </getElementsByClassName>
	
	getElementsByAttribute: function(attribute, value, parent) {
		if (!attribute && document.body.getAttribute) return;
		var nodes = (parent || document.body).getElementsByTagName('*');
		var els = [];
		for (var i = 0; i < nodes.length; i++)
			if (nodes[i].getAttribute(attribute) == value) els[els.length] = nodes[i];
		return els;
	},
	
	insertAfter: function(node, after) {
		var nextNode = after.nextSibling;
		if (!nextNode) after.parentNode.appendChild(node);
		else after.parentNode.insertBefore(node, nextNode);
	}
};

var Event = {
	add: function(el, e, func) {
		if (!(el && e && func)) return;
		if (el.addEventListener) el.addEventListener(e, func, false);
		else if (el.attachEvent) el.attachEvent('on' + e, func);
	},
	
	// Kills events, dead.
	stop: function(e) {
		e = e || window.event;
		e.cancelBubble = true;
		e.returnValue = false;
		if (e.stopPropagation) {
			e.stopPropagation();
			e.preventDefault();
		}
	},
	
	getTarget: function(e) {
		e = e || window.event;
		var targ = (e.target) ? e.target :
			(e.srcElement) ? e.srcElement :
			null;
		if (targ.nodeType == 3) targ = targ.parentNode;
	}
};

// Required Silverlight functions
function onErrorHandler(sender, args) { }
function onResizeHandler(sender, args) { }

navigator.isIE = (document.all && !window.opera);