// *** Global Variables ***

var PROTOTYPE_VERSION = parseFloat(Prototype.Version);

var isBrowserIE = document.all;

// *** Global Functions ***

function ABSTRACT_METHOD() {
	throw new Error('Abstract method');
}

function doOnLoad(func) {
	Event.observe(window, 'load', func);
}

function doOnUnload(func) {
	Event.observe(window, 'unload', func);
}

if (PROTOTYPE_VERSION >= 1.6) {
function doOnReady(func) {
	document.observe('dom:loaded', func);
}
}

function getFirstForm(formName) {
	var form = document.forms[formName];
	if (form) {
		return $(isArray(form) ? form[0] : form);
	}
	return null;
}

// Deprecated: Use either $() or getFirstForm().
function getForm(formName) {
	return $(document.forms[formName]);
}

function isArray(obj) {
	return (obj.length) && (!obj.elements);
}

function loadPage(url) {
	window.location = url;
}

function printPage() {
	window.print();
}

function makeUrl(baseUrl, params) {
	if (params) {
		var queryString = Object.toQueryString(params);
		if (queryString.length > 0) {
			var separator = baseUrl.include('?') ? '&' : '?';
			return baseUrl + separator + queryString;
		}
	}
	return baseUrl;
}

function passFormValuesToPage(baseUrl, form, options) {
	form = $(form);
	loadPage(makeUrl(baseUrl, form.getParams(options)));
}

// *** Class: document.viewport ***

if (PROTOTYPE_VERSION >= 1.6) {
document.viewport.getBottom = function() {
	return this.getHeight() + this.getScrollOffsets().top;
};

document.viewport.getRight = function() {
	return this.getWidth() + this.getScrollOffsets().left;
};
}

// *** Class: NumberUtils ***

var NumberUtils = {

	isDivisibleBy: function(num1, num2) {
		return ((num1 % num2) == 0);
	},

	formatDollar: function(number) {
		var result = number.toFixed(2);

		if (result == '-0.00') {
			result = '0.00';
		}

		// Add commas.
		var regex = /(-?\d+)(\d{3})/;
		while(regex.test(result)){
			result = result.replace(regex, "$1,$2");
		}

		return result;
	}
};

// *** Class: Array ***

Object.extend(Array.prototype, {
	add: function(obj) {
		var i = this.length;
		this[i] = obj;
		return i;
	},

	insert: function(index, obj) {
		for (var i = this.length; i > index; i--) {
			this[i] = this[i-1];
		}
		this[index] = obj;
	},

	remove: function(index) {
		if ((index >= 0) && (index < this.length)) {
			for (var i = index; i < this.length; i++) {
				this[i] = this[i+1];
			}
			this.length -= 1;
		}
	}
});

// *** Class: String ***

Object.extend(String.prototype, {
	equalsIgnoreCase: function(other) {
		return String.equalsIgnoreCase(this, other);
	},

	padLeft: function(len, ch) {
		ch = ch || ' ';
		return (this.length < len) ? (ch.times(len - this.length) + this) : this;
	},

	padRight: function(len, ch) {
		ch = ch || ' ';
		return (this.length < len) ? (this + ch.times(len - this.length)) : this;
	},

	padZero: function(len) {
		return this.padLeft(len, '0');
	}
});

String.equalsIgnoreCase = function(str1, str2) {
	str1 = (str1) ? str1.toUpperCase().toLowerCase() : str1;
	str2 = (str2) ? str2.toUpperCase().toLowerCase() : str2;
	return (str1 == str2);
};

String.padLeft = function(str, len) {
	str = (str || '').toString();
	return str.padLeft(len);
};

String.padRight = function(str, len) {
	str = (str || '').toString();
	return str.padRight(len);
};

String.padZero = function(str, len) {
	str = (str || '').toString();
	return str.padZero(len);
};

// *** Class: Date ***

Object.extend(Date.prototype, {

	addDays: function(days) {
		this.setDate(this.getDate() + days);
		return this;
	},

	addMonths: function(months) {
		this.setMonth(this.getMonth() + months);
		return this;
	},

	clearTime: function() {
		this.setHours(0);
		this.setMinutes(0);
		this.setSeconds(0);
		this.setMilliseconds(0);
		return this;
	},

	isInSameMonth: function(other) {
		return ((this.getFullYear() == other.getFullYear())
			&& (this.getMonth() == other.getMonth()));
	},

	getCopy: function() {
		return new Date(this.getTime());
	},

	getCopyPlusDays: function(days) {
		var result = this.getCopy();
		result.addDays(days);
		return result;
	},

	getCopyPlusMonths: function(months) {
		var result = this.getCopy();
		result.addMonths(months);
		return result;
	},

	getFirstOfMonth: function() {
		var result = this.getCopy().clearTime();
		result.setDate(1);
		return result;
	},

	formatMsDsYYYY: function() {
		return (this.getMonth() + 1) + '/' + this.getDate() + '/' + this.getFullYear();
	},

	formatMMsDDsYY: function() {
		return String.padZero((this.getMonth() + 1), 2) + '/' + String.padZero(this.getDate(), 2) + '/' + this.getFullYear().toString().substr(2, 2);
	},

	formatInputDate: function() {
		return this.formatMMsDDsYY();
	}
});

Date.getDaysInMonth = function(year, month) {
	if ((year >= 0) && (year <= 9999)) {
		if ((month >= 0) && (month <= 11)) {
			switch (month) {
				case  0: return 31;
				case  1: return Date.isLeapYear(year) ? 29 : 28;
				case  2: return 31;
				case  3: return 30;
				case  4: return 31;
				case  5: return 30;
				case  6: return 31;
				case  7: return 31;
				case  8: return 30;
				case  9: return 31;
				case 10: return 30;
				case 11: return 31;
			}
		}
	}
	return 0;
};

Date.isLeapYear = function(year) {
	return (NumberUtils.isDivisibleBy(year, 4)
		&& (!NumberUtils.isDivisibleBy(year, 100) || NumberUtils.isDivisibleBy(year, 400)));
};

Date.isValid = function(year, month, day) {
	if ((year >= 0) && (year <= 9999)) {
		if ((month >= 0) && (month <= 11)) {
			if ((day >=0) && (day <= Date.getDaysInMonth(year, month))) {
				return true;
			}
		}
	}
	return false;
};

Date.isValidMsDsYY = function(str) {
	var good = /^\d{1,2}([\/\-\.])\d{1,2}\1\d{2}$/;
	return (str.match(good) != null);
};

Date.isValidMsDsYYYY = function(str) {
	var good = /^\d{1,2}([\/\-\.])\d{1,2}\1\d{4}$/;
	return (str.match(good) != null);
};

Date.now = function() {
	return new Date();
};

Date.parseInputDate = function(str) {
	if (Date.isValidMsDsYY(str)) {
		return Date.parseMsDsYY(str);
	}
	if (Date.isValidMsDsYYYY(str)) {
		return Date.parseMsDsYYYY(str);
	}
	return null;
};

Date.parseMsDsYY = function(str) {
	if (Date.isValidMsDsYY(str)) {
		var separator = str.substr(str.length - 3, 1);
		var index1 = str.indexOf(separator);
		var index2 = str.indexOf(separator, index1 + 1);
		var month = parseInt(str.substring(0, index1), 10) - 1;
		var day = parseInt(str.substring(index1 + 1, index2), 10);
		var year = parseInt(str.substring(index2 + 1), 10);
		year += (year < 50) ? 2000 : 1900;
		if (Date.isValid(year, month, day)) {
			return new Date(year, month, day);
		}
	}
	return null;
};

Date.parseMsDsYYYY = function(str) {
	if (Date.isValidMsDsYYYY(str)) {
		var separator = str.substr(str.length - 5, 1);
		var index1 = str.indexOf(separator);
		var index2 = str.indexOf(separator, index1 + 1);
		var month = parseInt(str.substring(0, index1), 10) - 1;
		var day = parseInt(str.substring(index1 + 1, index2), 10);
		var year = parseInt(str.substring(index2 + 1), 10);
		if (Date.isValid(year, month, day)) {
			return new Date(year, month, day);
		}
	}
	return null;
};

Date.resolveInputDate = function(date) {
	if (date) {
		if (typeof date == 'string') {
			return Date.parseInputDate(date);
		}
		return date;
	}
	return null;
};

Date.today = function() {
	return Date.now().clearTime();
};

// *** Class: Point ***

var Point = Class.create({

	initialize: function(x, y) {
		this.x = x;
		this.y = y;
	}
});

// *** Class: ImageUtils ***

var ImageUtils = {};

ImageUtils._preloadedImages = null;

ImageUtils.create = function(src) {
	var image = new Image();
	image.src = src;
	return image;
};

ImageUtils.getPosition = function(image) {
	if (isBrowserIE) {
		var offset = $(image).cumulativeOffset();
		return new Point(offset.left, offset.top);
	} else  {
		return new Point(image.x, image.y);
	}
};

ImageUtils.preload = function(/* [0..N] or an array of image srcs */) {
	if (document.images) {
		$A(arguments).each(function(arg) {
			if (Object.isArray(arg)) {
				$(arg).each(function(obj) {
					ImageUtils.preload(obj);
				});
			} else {
				if (arg.indexOf("#") != 0) {
					ImageUtils._preloadedImages = ImageUtils._preloadedImages || [];
					ImageUtils._preloadedImages.add(ImageUtils.create(arg));
				}
			}
		});
	}
};

ImageUtils.setSrcForAll = function(images, src) {
	$(images).each(function(image) {
		image.src = src;
	});
};

ImageUtils.toggleSrc = function(image, src1, src2) {
	image = $(image);
	image.src = image.src.match(src1) ? src2 : src1;
};

ImageUtils.toggleSrcForAll = function(images, src1, src2) {
	$(images).each(function(image) {
		toggleSrc(image, src1, src2);
	});
};

// *** Class: Xml ***

var Xml = {

	getTag: function(xml, tagName) {
		if (xml) {
			var tags = xml.getElementsByTagName(tagName);
			if (tags && (tags.length > 0)) {
				return tags[0];
			}
		}
		return null;
	},

	getTagContent: function(tag, stripScripts) {
		if (tag) {
			var firstChild = tag.firstChild;
			if (firstChild) {
				var data = firstChild.data;
				if (data) {
					if (stripScripts) {
						data = data.stripScripts();
					}
					return data;
				}
			}
		}
		return null;
	}
};

// *** Form ***

if (PROTOTYPE_VERSION >= 1.6) {
Object.extend(Form.Methods, {
	getParamValue: function(form, elementName) {
		form = $(form);
		return Element.getParamValue(form.elements[elementName]);
	},

	getParams: function(form, options) {
		form = $(form);
		options = options || {};
		var params = new Object();
		$A(form.elements).each(
			function(e) {
				if (!params[e.name]
						&& (!options.includeClass || Element.hasClassName(e, options.includeClass))
						&& (!options.includeNames || options.includeNames.include(e.name))
						&& (!options.excludeNames || !options.excludeNames.include(e.name))) {
					params[e.name] = Form.Element.getParamValue(e);
				}
			}
		);
		return params;
	}
});
Element.addMethods();
};

// *** Element ***

if (PROTOTYPE_VERSION >= 1.6) {
	Object.extend(Form.Element.Methods, {
	getParamValue: function(element) {
		element = $(element);
		return (element.type == 'radio') ? $RF(element) : HelperText.getRealValue(element);
	}
});
Element.addMethods();
};

// *** Select Element ***

if (PROTOTYPE_VERSION >= 1.6) {
Element.addMethods('SELECT', {
	appendOption: function(select, value, text) {
		select = $(select);
		var option = new Option(text, value);
		try {
			select.add(option, null);
		} catch(e) {
			select.add(option); // IE
		}
	},

	getIndexOfValue: function(select, value) {
		select = $(select);
		for (var i = 0; i < select.length; i++) {
			if (select.options[i].value == value) {
				return i;
			}
		}
		return -1;
	},

	insertOptionAt: function(select, index, value, text) {
		select = $(select);
		if (index >= 0) {
			if (index < select.length) {
				var option = new Option(text, value);
				try {
					select.add(option, select.options[index]);
				} catch(e) {
					select.add(option, index); // IE
				}
			} else {
				select.appendOption(value, text);
			}
		}
	},

	isValidIndex: function(select, index) {
		select = $(select);
		return (index >= 0) && (index < select.length);
	},

	removeAllOptions: function(select) {
		select = $(select);
		select.removeAllOptionsExcept(0);
	},

	removeAllOptionsExcept: function(select, count) {
		select = $(select);
		if (count < 0) {
			count = 0;
		}
		for (var i = select.length - 1; i >= count; i--) {
			select.remove(i);
		}
	},

	removeOptionAt: function(select, index) {
		select = $(select);
		if (select.isValidIndex(index)) {
			select.remove(index);
		}
	},

	replaceOptionAt: function(select, index, value, text) {
		select = $(select);
		if (index >= 0) {
			select.removeOptionAt(index);
			select.insertOptionAt(index, value, text);
		}
	},

	selectOptionByValue: function(select, value) {
		select = $(select);
		select.selectedIndex = select.getIndexOfValue(value);
		return select.selectedIndex;
	},

	submit: function(select) {
		select = $(select);
		if (select.value && !select.value.empty()) {
			select.form.submit();
			return true;
		}
		return false;
	}
});
}

// *** Class: RadioGroup ***

var RadioGroup = Class.create();

RadioGroup.prototype = {
	initialize: function(element, radioName) {
		element = $(element);
		if (element.type == 'radio') {
			this.form = $(element.form);
			this.radioName = element.name;
		} else if (element.tagName.toLowerCase() == 'form') {
			this.form = element;
			this.radioName = radioName;
		} else {
			throw 'Invalid arguments to RadioGroup constructor';
		}
	},

	enable: function() {
		this.getButtons().each(
			function(re) { re.enable(); }
		);
		return this;
	},

	disable: function() {
		this.getButtons().each(
			function(re) { re.disable(); }
		);
		return this;
	},

	getButton: function(value) {
		return this.getButtons().find(
			function(re) { return (re.value == value); }
		);
	},

	getButtonAt: function(index) {
		return this.getButtons()[index];
	},

	getButtons: function() {
		return $A(this.form.getInputs('radio', this.radioName));
	},

	getCheckedButton: function() {
		return this.getButtons().find(
			function(re) { return re.checked; }
		);
	},

	getSelectedIndex: function() {
		var result = -1;
		this.getButtons().each(function(button, index) {
			if (button.checked) {
				result = index;
				throw $break;
			}
		});
		return result;
	},

	getValue: function() {
		var checkedButton = this.getCheckedButton();
		return (checkedButton) ? $F(checkedButton) : undefined;
	},

	setSelectedIndex: function(index) {
		var button = this.getButtonAt(index);
		if (button) {
			button.checked = true;
		} else {
			this.clear();
		}
		return this;
	},

	setValue: function(value) {
		var button = this.getButton(value);
		if (button) {
			button.checked = true;
		} else {
			this.clear();
		}
		return this;
	},

	clear: function() {
		this.getButtons().each(
			function(re) { re.checked = false; }
		);
		return this;
	}
};

function $RF(element, radioName) {
	return (new RadioGroup(element, radioName)).getValue();
}

// *** Class: Toggle ***

var Toggle = Class.create({

	initialize: function() {},

	getState: function() { ABSTRACT_METHOD(); },

	off: function() { ABSTRACT_METHOD(); },

	on: function() { ABSTRACT_METHOD(); },

	setState: function(state) {
		if (state) {
			this.on();
		} else {
			this.off();
		}
	},

	toggle: function() {
		setState(!getState());
	}
});

// *** Class: ToggleImage ***

var ToggleImage = Class.create(Toggle, {

	initialize: function($super, image, onSrc, offSrc) {
		$super();
		this.image = $(image);
		this.onSrc = onSrc;
		this.offSrc = offSrc;
	},

	getState: function() {
		return (this.image.src == this.onSrc);
	},

	off: function() {
		this.image.src = this.offSrc;
	},

	on: function() {
		this.image.src = this.onSrc;
	}
});

// *** Class: ToggleClass ***

var ToggleClass = Class.create(Toggle, {

	initialize: function($super, element, onClass, offClass) {
		$super();
		this.element = $(element);
		this.onClass = onClass;
		this.offClass = offClass;
	},

	getState: function() {
		return this.element.hasClassName(this.onClass);
	},

	off: function() {
		this.element.removeClassName(this.onClass);
		this.element.addClassName(this.offClass);
	},

	on: function() {
		this.element.removeClassName(this.offClass);
		this.element.addClassName(this.onClass);
	}
});

// *** Class: Tab ***

var Tab = Class.create({

	initialize: function() {
		this.index = null;
		this.onClick = null;
	},

	off: function() { ABSTRACT_METHOD(); },

	on: function() { ABSTRACT_METHOD(); },

	setState: function(state) {
		if (state) {
			this.on();
		} else {
			this.off();
		}
	},

	_callOnClick: function() {
		if (this.onClick) {
			this.onClick.call(this, this.index);
			return true;
		}
		return false;
	}
});

// *** Class: AnchorTab ***

var AnchorTab = Class.create(Tab, {

	initialize: function($super, anchor) {
		$super();
		this.anchor = $(anchor);

		Event.observe(
			this.anchor,
			'click',
			(function(event) {
				if (this._callOnClick()) {
					Event.stop(event);
				}
			}).bindAsEventListener(this)
		);
	}
});

// *** Class: ToggleAnchorTab ***

var ToggleAnchorTab = Class.create(AnchorTab, {

	initialize: function($super, anchor, toggle) {
		$super(anchor);
		this.toggle = toggle;
	},

	off: function() {
		this.toggle.off();
	},

	on: function() {
		this.toggle.on();
	}
});

// *** Class: ToggleImageTab ***

var ToggleImageTab = Class.create(ToggleAnchorTab, {

	initialize: function($super, anchor, onSrc, offSrc) {
		anchor = $(anchor);
		$super(anchor, new ToggleImage(anchor.firstDescendant(), onSrc, offSrc));
	}
});

// *** Class: ToggleClassTab ***

var ToggleClassTab = Class.create(ToggleAnchorTab, {

	initialize: function($super, anchor, onClass, offClass) {
		anchor = $(anchor);
		$super(anchor, new ToggleClass(anchor, onClass, offClass));
	}
});

// *** Class: TabSet ***

var TabSet = Class.create({

	initialize: function() {
		this.tabs = [];
		this.onChange = null;
	},

	add: function(tab) {
		tab.index = this.tabs.add(tab);
		tab.onClick = (function(index) {
			this.showTab(index);
			this._callOnChange(index);
		}).bind(this);
	},

	showTab: function(index) {
		this.tabs.each(function(tab) {
			tab.setState(tab.index == index);
		});
	},

	_callOnChange: function(index) {
		if (this.onChange) {
			this.onChange.call(this, index);
			return true;
		}
		return false;
	}
});

// *** Class: Pane ***

var Pane = Class.create({

	initialize: function(element) {
		this.element = $(element);
		this.index = null;
	},

	hide: function() {
		this.element.hide();
	},

	show: function() {
		this.element.show();
	},

	setState: function(state) {
		if (state) {
			this.show();
		} else {
			this.hide();
		}
	}
});

// *** Class: PaneSet ***

var PaneSet = Class.create({

	initialize: function() {
		this.panes = [];
	},

	add: function(pane) {
		pane.index = this.panes.add(pane);
	},

	showPane: function(index) {
		this.panes.each(function(pane) {
			pane.setState(pane.index == index);
		});
	}
});

// *** Class: TabbedPaneSet ***

var TabbedPaneSet = Class.create({

	initialize: function(options) {
		options = options || {};

		this.autoHistory = options.autoHistory;
		this.paneSet = new PaneSet();
		this.tabSet = new TabSet();

		this.tabSet.onChange = (function(index) {
			this.paneSet.showPane(index);
			if (this.autoHistory) {
				dhtmlHistory.add(index);
			}
		}).bind(this);

		if (this.autoHistory) {
			dhtmlHistory.addListener((function(location) {
				this._showPane(location);
			}).bind(this));
		}
	},

	add: function(pane, tab) {
		this.paneSet.add(pane);
		this.tabSet.add(tab);
	},

	_showPane: function(index) {
		this.paneSet.showPane(index);
		this.tabSet.showTab(index);
	}
});

// *** Class: Marquee ***

var Marquee = Class.create({

	initialize: function(element, messages, interval) {
		this.element = $(element);
		this.messages = messages;
		this.interval = interval;

		this._timeoutId = null;
	},

	start: function() {
		this._messageIndex = 0;
		this._showMessage();
	},

	stop: function() {
		if (this._timeoutId) {
			clearTimeout(this._timeoutId);
		}
	},

	_showMessage: function() {
		this.element.update(this.messages[this._messageIndex]);
		this._messageIndex++;
		if (this._messageIndex == this.messages.length) {
			this._messageIndex = 0;
		}
		this._timeoutId = setTimeout((function() { this._showMessage(); }).bind(this), this.interval);
	}
});

// *** Class: SlideShow ***

var SlideShow = Class.create({

	initialize: function(image, imageSrcs, options) {
		options = options || {};

		this.basePath = options.basePath || null;
		this.image = $(image);
		this.imageSrcs = imageSrcs;
		this.index = 0;
		this.onChange = options.onChange || null;
	},

	_getNextIndex: function(direction) {
		var result = this.index + direction;
		if (result < 0) { result = this.imageSrcs.length - 1; }
		if (result >= this.imageSrcs.length) { result = 0; }
		return result;
	},

	_setIndex: function(index) {
		if (this.index != index) {
			this.index = index;

			if (isBrowserIE) {
				this.image.style.filter = 'blendTrans(duration=1)';
				this.image.filters.blendTrans.Apply();
			}
			this.image.src = (this.basePath ? this.basePath : '') + this.imageSrcs[this.index];
			if (isBrowserIE) {
				this.image.filters.blendTrans.Play();
			}

			if (this.onChange) {
				this.onChange.call(null, this.index);
			}
		}
	},

	nextPicture: function(direction) {
		this._setIndex(this._getNextIndex(direction));
	},

	showPicture: function(index) {
		this._setIndex(index);
	}
});

// *** Class: HelperText ***

var HelperText = {
	_CSS_CLASS_NAME: 'helpertext',

	hide: function(element) {
		element = $(element);
		if (element.helperText) {
			if (element.hasClassName(HelperText._CSS_CLASS_NAME)) {
				element.removeClassName(HelperText._CSS_CLASS_NAME);
				if (element.value == element.helperText) {
					element.value = '';
				}
			}
		}
	},

	show: function(element) {
		element = $(element);
		if (element.helperText) {
			if (element.value == '') {
				element.addClassName(HelperText._CSS_CLASS_NAME);
				element.value = element.helperText;
			}
		}
	},

	getRealValue: function(element) {
		element = $(element);
		var value = element.value;
		if (element.hasClassName(HelperText._CSS_CLASS_NAME)) {
			if (value == element.helperText) {
				value = '';
			}
		}
		return value;
	},

	decorate: function(element, helperText) {
		element = $(element);

		element.helperText = helperText;

		Event.observe(
			element,
			'focus',
			(function() { HelperText.hide(this); }).bindAsEventListener(element)
		);

		Event.observe(
			element,
			'blur',
			(function() { HelperText.show(this); }).bindAsEventListener(element)
		);

		if (element.form) {
			Event.observe(
				element.form,
				'submit',
				(function() { HelperText.hide(this); }).bindAsEventListener(element)
			);
		};

		HelperText.show(element);
	},

	decorateForm: function(form, infos) {
		form = $(form);
		infos.each(
			function(info) {
				HelperText.decorate(form.elements[info.element], info.text);
			}
		);
	}
};

// *** Class: Ajax.MultiUpdater ***

if (PROTOTYPE_VERSION >= 1.6) {
Ajax.MultiUpdater = Class.create(Ajax.Request, {

	initialize: function($super, containers, url, options) {
		var successContainerMap = this._createContainerMap(containers.success || containers);
		this.containers = {
			success: successContainerMap,
			failure: containers.failure
		};

		options = options || {};
		var onComplete = options.onComplete;
		options.onComplete = (function(response, param) {
			this.updateContent(response);
			if (Object.isFunction(onComplete)) onComplete(response, param);
		}).bind(this);

		$super(url, options);
	},

	updateContent: function(response) {
		if (this.success() || !this.containers.failure) {
			var blocksTag = Xml.getTag(response.responseXML, Ajax.MultiUpdater._BLOCKS_TAG_NAME);
			if (blocksTag) {
				var blockTags = $A(blocksTag.getElementsByTagName(Ajax.MultiUpdater._BLOCK_TAG_NAME));
				if (blockTags) {
					blockTags.each((function(blockTag, index) {
						var blockName = blockTag.getAttribute(Ajax.MultiUpdater._BLOCK_NAME_ATTR_NAME) || index;
						var content = Xml.getTagContent(blockTag, !this.options.evalScripts);
						var receiver = this._getContainer(blockName);
						this._updateReceiver(receiver, content, this.options.insertion);
					}).bind(this));
				}
			}
		} else {
			var receiver = this.containers.failure;
			var content = response.responseText;
			if (!this.options.evalScripts) {
				content = content.stripScripts();
			}
			this._updateReceiver(receiver, content, this.options.insertion);
		}

		if (this.success()) {
			if (this.onComplete) {
				this.onComplete.bind(this).defer();
			}
		}
	},

	_createContainerMap: function(containers) {
		var map = {};
		containers.each(function(container, index) {
			if (container.name) {
				map[container.name] = container.element;
			} else {
				map[index] = container;
			}
		});
		return map;
	},

	_getContainer: function(blockName) {
		var container = this.containers.success[blockName];
		if (container) {
			return $(container);
		}
		return null;
	},

	_updateReceiver: function(receiver, content, insertion) {
		if (receiver) {
			if (insertion) {
				if (Object.isString(insertion)) {
					var insertions = {};
					insertions[insertion] = content;
					receiver.insert(insertions);
				} else {
					insertion(receiver, content);
				}
			} else {
				receiver.update(content);
			}
		}
	}
});

Ajax.MultiUpdater._BLOCKS_TAG_NAME      = 'blocks';
Ajax.MultiUpdater._BLOCK_TAG_NAME       = 'block';
Ajax.MultiUpdater._BLOCK_NAME_ATTR_NAME = 'name';
}

// *** Deprecated ***

// Used by <mlt:swapImageLink>.
function IMAGES_swapRestore() {
	var i,x,a=document.IMAGES_sr; for(i=0; a && i<a.length && (x=a[i]) && x.oSrc; i++) x.src=x.oSrc;
}

// Used by <mlt:swapImageLink>.
function IMAGES_findObj(n,d) {
	var p,i,x; if(!d) d=document; if((p=n.indexOf("?"))>0 && parent.frames.length) {
		d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p); }
	if(!(x=d[n]) && d.all) x=d.all[n]; for(i=0; !x && i<d.forms.length; i++) x=d.forms[i][n];
	for(i=0; !x && d.layers && i<d.layers.length; i++) x=IMAGES_findObj(n,d.layers[i].document);
	if(!x && document.getElementById) x=document.getElementById(n); return x;
}

// Used by <mlt:swapImageLink>.
function IMAGES_swap() {
	var i,j=0,x,a=IMAGES_swap.arguments; document.IMAGES_sr=new Array; for(i=0; i<(a.length-1); i+=2)
		if((x=IMAGES_findObj(a[i]))!=null){ document.IMAGES_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+1]; }
}
