function nonW3CFixes_customHasClassName(sClassName) {
	var oRegExp = new RegExp("(^|\\s)" + sClassName + "(\\s|$)");
	return oRegExp.test(this.className);
}

function nonW3CFixes_addCustomHasClassName() {
	// for browsers that don't support hasClassName natively
	if (!this.hasClassName) {
		this.hasClassName = nonW3CFixes_customHasClassName;

		// add the custom function to all loaded elements
		var oaElements = this.getElementsByTagName('*');
		for (var i = 0; i < oaElements.length; i++) {
			if (!oaElements[i].hasClassName) {
				oaElements[i].hasClassName = nonW3CFixes_customHasClassName;
			}
		}
	}
}

function nonW3CFixes_customGetElementsByClassName(sClassName) {
	var oaReturnedElements = new Array();

	// get all child elements of the caller element
	var oaElements = this.getElementsByTagName('*');
	for (var i = 0; i  < oaElements.length; i++) {
		// some elements might be created after the nonW3CFixes_init function finishes,
		// so hasClassName might not be a method of the element
		if (!oaElements[i].hasClassName) {
			oaElements[i].hasClassName = nonW3CFixes_customHasClassName;
		}

		// save the found element in the return array
		if (oaElements[i].hasClassName(sClassName)) {
			oaReturnedElements.push(oaElements[i]);
		}
	}

	return oaReturnedElements;
}

function nonW3CFixes_addCustomGetElementsByClassName() {
	// for browsers that don't support getElementsByClassName natively
	if (!this.getElementsByClassName) {
		// add the custom function to the document
		this.getElementsByClassName = nonW3CFixes_customGetElementsByClassName;

		// add the custom function to all loaded elements
		var oaElements = this.getElementsByTagName('*');
		for (var i = 0; i < oaElements.length; i++) {
			if (!oaElements[i].getElementsByClassName) {
				oaElements[i].getElementsByClassName = nonW3CFixes_customGetElementsByClassName;
			}
		}
	}
}

function nonW3CFixes_getPosition(obj) {
	var curleft = curtop = 0;

	if (obj.offsetParent) {
		do {
			curtop += obj.offsetTop;
			curleft += obj.offsetLeft;
		} while (obj = obj.offsetParent);
	}

	return [curtop, curleft];
}

function nonW3CFixes_init() {
	if (!this.hasClassName) {
		this.nonW3CFixes_addCustomHasClassName = nonW3CFixes_addCustomHasClassName;
		this.nonW3CFixes_addCustomHasClassName();
	}

	if (!this.getElementsByClassName) {
		this.nonW3CFixes_addCustomGetElementsByClassName = nonW3CFixes_addCustomGetElementsByClassName;
		this.nonW3CFixes_addCustomGetElementsByClassName();
	}

	if (!window.XMLHttpRequest && window.ActiveXObject) {
		// !!! pass 'MSXML2.XMLHTTP.3.0' to the constructor !!!
		window.XMLHttpRequest = ActiveXObject;
	}

	if (typeof(JSON) == 'undefined' && window.jsonParse) {
		window.JSON = { parse: window.jsonParse };
	}

	if (typeof(String.prototype.trim) == 'undefined') {
		String.prototype.trim = function() {
			var str = this;
			str = str.replace(/^\s\s*/, ''),
			ws = /\s/,
			i = str.length;
			while (ws.test(str.charAt(--i)));
			return str.slice(0, i + 1);
		}
	}
}
