var ajaxUpdateMultiple = function() {
	function getRequest() {
		if (window.XMLHttpRequest)
			return new XMLHttpRequest();
		else if (window.ActiveXObject)
			return new ActiveXObject("Microsoft.XMLHTTP");
		else
			alert('ajax not supported');
		return null;
	}

	function recurseTags(text, depth, trimmed) {
		if (depth == -1) {
			return trimmed;
		}

		var openingTag = /\<div/;
		var closingTag = /\<\/div\>/;

		var nextClose = text.search(closingTag);
		var nextOpen = text.search(openingTag);

		//Cheat and make the next if statement match properly
		if (nextOpen == -1)
			nextOpen = nextClose + 1;

		if (nextOpen < nextClose) {
			text = text.substring(nextOpen);
			var endoftag = text.indexOf('>');
			text = text.substring(endoftag);
			trimmed += nextOpen + endoftag;
			return recurseTags(text, depth + 1, trimmed);
		}
		else if (nextOpen > nextClose) {
			text = text.substring(nextClose);
			var endoftag = text.indexOf('>');
			text = text.substring(endoftag);
			trimmed += nextClose + endoftag;
			return recurseTags(text, depth - 1, trimmed);
		}
	}

	function getDiv(id, text) {
		//Find the start of the div
		var pattern = '\<div[^\>]*?id="'+id+'"[^\>]*?\>';
		var regex = new RegExp(pattern);

		var beginning = text.search(regex);
		//If it exists - find the end
		if (beginning != -1) {
			//Crop the text
			var subtext = text.substring(beginning);
			//Move to the end of the tag
			subtext = subtext.substring(subtext.indexOf('>') + 1);

			//Can't regex nested divs - humping lama, or whatever
			var closeTag = recurseTags(subtext, 0, 0);

			return subtext.substring(0, closeTag);
		}
		//doesn't exist
		return null;
	}

	function handleChange(req, divs, callback) {
		if(req.readyState == 4) {
			if (req.status == 200) {

				if (divs) {
					var html = req.responseText;

					if( typeof(divs) == 'string' ) {
						divs = [divs];
					}

					for (var i=0; i<divs.length; i++) {
						document.getElementById(divs[i]).innerHTML = getDiv(divs[i], html);
					}
				}

				if (callback)
					callback(req.responseText);
			}
			else {
				alert("Ajax request failed.");
			}
		}
	}

	function handleParams(params) {
		if(!params) {
			return null;
		}
		else {
			var encoded = "";
			for (var field in params) {
				fieldval = eval('params.'+field);
				encoded += field + '=' + fieldval + '&';
			}
			return encoded;
		}
	}

	function getParameter(data, requested) {
		var reqParam = null;
		if (!data) {
			return reqParam;
		}
		else {
			for (var field in data) {
				if (field == requested) {
					reqParam = eval('data.'+field);
				}
			}
			return reqParam;
		}
	}

	return function(uri, data) {
		var divs = getParameter(data, 'divs');
		var params = getParameter(data, 'params');
		var callback = getParameter(data, 'callback');

		var request = getRequest();
		request.open('POST', uri, true);    //Only need posts with CI
		request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		request.onreadystatechange = function() { handleChange(request, divs, callback) };
		request.send(handleParams(params));
		return request;
	};
}();