diff --git a/planetstack/core/static/log4javascript-1.4.6/log4javascript_uncompressed.js b/planetstack/core/static/log4javascript-1.4.6/log4javascript_uncompressed.js
new file mode 100644
index 0000000..a644e3b
--- /dev/null
+++ b/planetstack/core/static/log4javascript-1.4.6/log4javascript_uncompressed.js
@@ -0,0 +1,5879 @@
+/**
+ * Copyright 2013 Tim Down.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * log4javascript
+ *
+ * log4javascript is a logging framework for JavaScript based on log4j
+ * for Java. This file contains all core log4javascript code and is the only
+ * file required to use log4javascript, unless you require support for
+ * document.domain, in which case you will also need console.html, which must be
+ * stored in the same directory as the main log4javascript.js file.
+ *
+ * Author: Tim Down <tim@log4javascript.org>
+ * Version: 1.4.6
+ * Edition: log4javascript
+ * Build date: 19 March 2013
+ * Website: http://log4javascript.org
+ */
+
+/* -------------------------------------------------------------------------- */
+// Array-related stuff
+
+// Next three methods are solely for IE5, which is missing them
+if (!Array.prototype.push) {
+	Array.prototype.push = function() {
+		for (var i = 0, len = arguments.length; i < len; i++){
+			this[this.length] = arguments[i];
+		}
+		return this.length;
+	};
+}
+
+if (!Array.prototype.shift) {
+	Array.prototype.shift = function() {
+		if (this.length > 0) {
+			var firstItem = this[0];
+			for (var i = 0, len = this.length - 1; i < len; i++) {
+				this[i] = this[i + 1];
+			}
+			this.length = this.length - 1;
+			return firstItem;
+		}
+	};
+}
+
+if (!Array.prototype.splice) {
+	Array.prototype.splice = function(startIndex, deleteCount) {
+		var itemsAfterDeleted = this.slice(startIndex + deleteCount);
+		var itemsDeleted = this.slice(startIndex, startIndex + deleteCount);
+		this.length = startIndex;
+		// Copy the arguments into a proper Array object
+		var argumentsArray = [];
+		for (var i = 0, len = arguments.length; i < len; i++) {
+			argumentsArray[i] = arguments[i];
+		}
+		var itemsToAppend = (argumentsArray.length > 2) ?
+			itemsAfterDeleted = argumentsArray.slice(2).concat(itemsAfterDeleted) : itemsAfterDeleted;
+		for (i = 0, len = itemsToAppend.length; i < len; i++) {
+			this.push(itemsToAppend[i]);
+		}
+		return itemsDeleted;
+	};
+}
+
+/* -------------------------------------------------------------------------- */
+
+var log4javascript = (function() {
+
+	function isUndefined(obj) {
+		return typeof obj == "undefined";
+	}
+
+	/* ---------------------------------------------------------------------- */
+	// Custom event support
+
+	function EventSupport() {}
+
+	EventSupport.prototype = {
+		eventTypes: [],
+		eventListeners: {},
+		setEventTypes: function(eventTypesParam) {
+			if (eventTypesParam instanceof Array) {
+				this.eventTypes = eventTypesParam;
+				this.eventListeners = {};
+				for (var i = 0, len = this.eventTypes.length; i < len; i++) {
+					this.eventListeners[this.eventTypes[i]] = [];
+				}
+			} else {
+				handleError("log4javascript.EventSupport [" + this + "]: setEventTypes: eventTypes parameter must be an Array");
+			}
+		},
+
+		addEventListener: function(eventType, listener) {
+			if (typeof listener == "function") {
+				if (!array_contains(this.eventTypes, eventType)) {
+					handleError("log4javascript.EventSupport [" + this + "]: addEventListener: no event called '" + eventType + "'");
+				}
+				this.eventListeners[eventType].push(listener);
+			} else {
+				handleError("log4javascript.EventSupport [" + this + "]: addEventListener: listener must be a function");
+			}
+		},
+
+		removeEventListener: function(eventType, listener) {
+			if (typeof listener == "function") {
+				if (!array_contains(this.eventTypes, eventType)) {
+					handleError("log4javascript.EventSupport [" + this + "]: removeEventListener: no event called '" + eventType + "'");
+				}
+				array_remove(this.eventListeners[eventType], listener);
+			} else {
+				handleError("log4javascript.EventSupport [" + this + "]: removeEventListener: listener must be a function");
+			}
+		},
+
+		dispatchEvent: function(eventType, eventArgs) {
+			if (array_contains(this.eventTypes, eventType)) {
+				var listeners = this.eventListeners[eventType];
+				for (var i = 0, len = listeners.length; i < len; i++) {
+					listeners[i](this, eventType, eventArgs);
+				}
+			} else {
+				handleError("log4javascript.EventSupport [" + this + "]: dispatchEvent: no event called '" + eventType + "'");
+			}
+		}
+	};
+
+	/* -------------------------------------------------------------------------- */
+
+	var applicationStartDate = new Date();
+	var uniqueId = "log4javascript_" + applicationStartDate.getTime() + "_" +
+		Math.floor(Math.random() * 100000000);
+	var emptyFunction = function() {};
+	var newLine = "\r\n";
+	var pageLoaded = false;
+
+	// Create main log4javascript object; this will be assigned public properties
+	function Log4JavaScript() {}
+	Log4JavaScript.prototype = new EventSupport();
+
+	log4javascript = new Log4JavaScript();
+	log4javascript.version = "1.4.6";
+	log4javascript.edition = "log4javascript";
+
+	/* -------------------------------------------------------------------------- */
+	// Utility functions
+
+	function toStr(obj) {
+		if (obj && obj.toString) {
+			return obj.toString();
+		} else {
+			return String(obj);
+		}
+	}
+
+	function getExceptionMessage(ex) {
+		if (ex.message) {
+			return ex.message;
+		} else if (ex.description) {
+			return ex.description;
+		} else {
+			return toStr(ex);
+		}
+	}
+
+	// Gets the portion of the URL after the last slash
+	function getUrlFileName(url) {
+		var lastSlashIndex = Math.max(url.lastIndexOf("/"), url.lastIndexOf("\\"));
+		return url.substr(lastSlashIndex + 1);
+	}
+
+	// Returns a nicely formatted representation of an error
+	function getExceptionStringRep(ex) {
+		if (ex) {
+			var exStr = "Exception: " + getExceptionMessage(ex);
+			try {
+				if (ex.lineNumber) {
+					exStr += " on line number " + ex.lineNumber;
+				}
+				if (ex.fileName) {
+					exStr += " in file " + getUrlFileName(ex.fileName);
+				}
+			} catch (localEx) {
+				logLog.warn("Unable to obtain file and line information for error");
+			}
+			if (showStackTraces && ex.stack) {
+				exStr += newLine + "Stack trace:" + newLine + ex.stack;
+			}
+			return exStr;
+		}
+		return null;
+	}
+
+	function bool(obj) {
+		return Boolean(obj);
+	}
+
+	function trim(str) {
+		return str.replace(/^\s+/, "").replace(/\s+$/, "");
+	}
+
+	function splitIntoLines(text) {
+		// Ensure all line breaks are \n only
+		var text2 = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
+		return text2.split("\n");
+	}
+
+	var urlEncode = (typeof window.encodeURIComponent != "undefined") ?
+		function(str) {
+			return encodeURIComponent(str);
+		}: 
+		function(str) {
+			return escape(str).replace(/\+/g, "%2B").replace(/"/g, "%22").replace(/'/g, "%27").replace(/\//g, "%2F").replace(/=/g, "%3D");
+		};
+
+	var urlDecode = (typeof window.decodeURIComponent != "undefined") ?
+		function(str) {
+			return decodeURIComponent(str);
+		}: 
+		function(str) {
+			return unescape(str).replace(/%2B/g, "+").replace(/%22/g, "\"").replace(/%27/g, "'").replace(/%2F/g, "/").replace(/%3D/g, "=");
+		};
+
+	function array_remove(arr, val) {
+		var index = -1;
+		for (var i = 0, len = arr.length; i < len; i++) {
+			if (arr[i] === val) {
+				index = i;
+				break;
+			}
+		}
+		if (index >= 0) {
+			arr.splice(index, 1);
+			return true;
+		} else {
+			return false;
+		}
+	}
+
+	function array_contains(arr, val) {
+		for(var i = 0, len = arr.length; i < len; i++) {
+			if (arr[i] == val) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	function extractBooleanFromParam(param, defaultValue) {
+		if (isUndefined(param)) {
+			return defaultValue;
+		} else {
+			return bool(param);
+		}
+	}
+
+	function extractStringFromParam(param, defaultValue) {
+		if (isUndefined(param)) {
+			return defaultValue;
+		} else {
+			return String(param);
+		}
+	}
+
+	function extractIntFromParam(param, defaultValue) {
+		if (isUndefined(param)) {
+			return defaultValue;
+		} else {
+			try {
+				var value = parseInt(param, 10);
+				return isNaN(value) ? defaultValue : value;
+			} catch (ex) {
+				logLog.warn("Invalid int param " + param, ex);
+				return defaultValue;
+			}
+		}
+	}
+
+	function extractFunctionFromParam(param, defaultValue) {
+		if (typeof param == "function") {
+			return param;
+		} else {
+			return defaultValue;
+		}
+	}
+
+	function isError(err) {
+		return (err instanceof Error);
+	}
+
+	if (!Function.prototype.apply){
+		Function.prototype.apply = function(obj, args) {
+			var methodName = "__apply__";
+			if (typeof obj[methodName] != "undefined") {
+				methodName += String(Math.random()).substr(2);
+			}
+			obj[methodName] = this;
+
+			var argsStrings = [];
+			for (var i = 0, len = args.length; i < len; i++) {
+				argsStrings[i] = "args[" + i + "]";
+			}
+			var script = "obj." + methodName + "(" + argsStrings.join(",") + ")";
+			var returnValue = eval(script);
+			delete obj[methodName];
+			return returnValue;
+		};
+	}
+
+	if (!Function.prototype.call){
+		Function.prototype.call = function(obj) {
+			var args = [];
+			for (var i = 1, len = arguments.length; i < len; i++) {
+				args[i - 1] = arguments[i];
+			}
+			return this.apply(obj, args);
+		};
+	}
+
+	function getListenersPropertyName(eventName) {
+		return "__log4javascript_listeners__" + eventName;
+	}
+
+	function addEvent(node, eventName, listener, useCapture, win) {
+		win = win ? win : window;
+		if (node.addEventListener) {
+			node.addEventListener(eventName, listener, useCapture);
+		} else if (node.attachEvent) {
+			node.attachEvent("on" + eventName, listener);
+		} else {
+			var propertyName = getListenersPropertyName(eventName);
+			if (!node[propertyName]) {
+				node[propertyName] = [];
+				// Set event handler
+				node["on" + eventName] = function(evt) {
+					evt = getEvent(evt, win);
+					var listenersPropertyName = getListenersPropertyName(eventName);
+
+					// Clone the array of listeners to leave the original untouched
+					var listeners = this[listenersPropertyName].concat([]);
+					var currentListener;
+
+					// Call each listener in turn
+					while ((currentListener = listeners.shift())) {
+						currentListener.call(this, evt);
+					}
+				};
+			}
+			node[propertyName].push(listener);
+		}
+	}
+
+	function removeEvent(node, eventName, listener, useCapture) {
+		if (node.removeEventListener) {
+			node.removeEventListener(eventName, listener, useCapture);
+		} else if (node.detachEvent) {
+			node.detachEvent("on" + eventName, listener);
+		} else {
+			var propertyName = getListenersPropertyName(eventName);
+			if (node[propertyName]) {
+				array_remove(node[propertyName], listener);
+			}
+		}
+	}
+
+	function getEvent(evt, win) {
+		win = win ? win : window;
+		return evt ? evt : win.event;
+	}
+
+	function stopEventPropagation(evt) {
+		if (evt.stopPropagation) {
+			evt.stopPropagation();
+		} else if (typeof evt.cancelBubble != "undefined") {
+			evt.cancelBubble = true;
+		}
+		evt.returnValue = false;
+	}
+
+	/* ---------------------------------------------------------------------- */
+	// Simple logging for log4javascript itself
+
+	var logLog = {
+		quietMode: false,
+
+		debugMessages: [],
+
+		setQuietMode: function(quietMode) {
+			this.quietMode = bool(quietMode);
+		},
+
+		numberOfErrors: 0,
+
+		alertAllErrors: false,
+
+		setAlertAllErrors: function(alertAllErrors) {
+			this.alertAllErrors = alertAllErrors;
+		},
+
+		debug: function(message) {
+			this.debugMessages.push(message);
+		},
+
+		displayDebug: function() {
+			alert(this.debugMessages.join(newLine));
+		},
+
+		warn: function(message, exception) {
+		},
+
+		error: function(message, exception) {
+			if (++this.numberOfErrors == 1 || this.alertAllErrors) {
+				if (!this.quietMode) {
+					var alertMessage = "log4javascript error: " + message;
+					if (exception) {
+						alertMessage += newLine + newLine + "Original error: " + getExceptionStringRep(exception);
+					}
+					alert(alertMessage);
+				}
+			}
+		}
+	};
+	log4javascript.logLog = logLog;
+
+	log4javascript.setEventTypes(["load", "error"]);
+
+	function handleError(message, exception) {
+		logLog.error(message, exception);
+		log4javascript.dispatchEvent("error", { "message": message, "exception": exception });
+	}
+
+	log4javascript.handleError = handleError;
+
+	/* ---------------------------------------------------------------------- */
+
+	var enabled = !((typeof log4javascript_disabled != "undefined") &&
+					log4javascript_disabled);
+
+	log4javascript.setEnabled = function(enable) {
+		enabled = bool(enable);
+	};
+
+	log4javascript.isEnabled = function() {
+		return enabled;
+	};
+
+	var useTimeStampsInMilliseconds = true;
+
+	log4javascript.setTimeStampsInMilliseconds = function(timeStampsInMilliseconds) {
+		useTimeStampsInMilliseconds = bool(timeStampsInMilliseconds);
+	};
+
+	log4javascript.isTimeStampsInMilliseconds = function() {
+		return useTimeStampsInMilliseconds;
+	};
+	
+
+	// This evaluates the given expression in the current scope, thus allowing
+	// scripts to access private variables. Particularly useful for testing
+	log4javascript.evalInScope = function(expr) {
+		return eval(expr);
+	};
+
+	var showStackTraces = false;
+
+	log4javascript.setShowStackTraces = function(show) {
+		showStackTraces = bool(show);
+	};
+
+	/* ---------------------------------------------------------------------- */
+	// Levels
+
+	var Level = function(level, name) {
+		this.level = level;
+		this.name = name;
+	};
+
+	Level.prototype = {
+		toString: function() {
+			return this.name;
+		},
+		equals: function(level) {
+			return this.level == level.level;
+		},
+		isGreaterOrEqual: function(level) {
+			return this.level >= level.level;
+		}
+	};
+
+	Level.ALL = new Level(Number.MIN_VALUE, "ALL");
+	Level.TRACE = new Level(10000, "TRACE");
+	Level.DEBUG = new Level(20000, "DEBUG");
+	Level.INFO = new Level(30000, "INFO");
+	Level.WARN = new Level(40000, "WARN");
+	Level.ERROR = new Level(50000, "ERROR");
+	Level.FATAL = new Level(60000, "FATAL");
+	Level.OFF = new Level(Number.MAX_VALUE, "OFF");
+
+	log4javascript.Level = Level;
+
+	/* ---------------------------------------------------------------------- */
+	// Timers
+
+	function Timer(name, level) {
+		this.name = name;
+		this.level = isUndefined(level) ? Level.INFO : level;
+		this.start = new Date();
+	}
+
+	Timer.prototype.getElapsedTime = function() {
+		return new Date().getTime() - this.start.getTime();
+	};
+
+	/* ---------------------------------------------------------------------- */
+	// Loggers
+
+	var anonymousLoggerName = "[anonymous]";
+	var defaultLoggerName = "[default]";
+	var nullLoggerName = "[null]";
+	var rootLoggerName = "root";
+
+	function Logger(name) {
+		this.name = name;
+		this.parent = null;
+		this.children = [];
+
+		var appenders = [];
+		var loggerLevel = null;
+		var isRoot = (this.name === rootLoggerName);
+		var isNull = (this.name === nullLoggerName);
+
+		var appenderCache = null;
+		var appenderCacheInvalidated = false;
+		
+		this.addChild = function(childLogger) {
+			this.children.push(childLogger);
+			childLogger.parent = this;
+			childLogger.invalidateAppenderCache();
+		};
+
+		// Additivity
+		var additive = true;
+		this.getAdditivity = function() {
+			return additive;
+		};
+
+		this.setAdditivity = function(additivity) {
+			var valueChanged = (additive != additivity);
+			additive = additivity;
+			if (valueChanged) {
+				this.invalidateAppenderCache();
+			}
+		};
+
+		// Create methods that use the appenders variable in this scope
+		this.addAppender = function(appender) {
+			if (isNull) {
+				handleError("Logger.addAppender: you may not add an appender to the null logger");
+			} else {
+				if (appender instanceof log4javascript.Appender) {
+					if (!array_contains(appenders, appender)) {
+						appenders.push(appender);
+						appender.setAddedToLogger(this);
+						this.invalidateAppenderCache();
+					}
+				} else {
+					handleError("Logger.addAppender: appender supplied ('" +
+						toStr(appender) + "') is not a subclass of Appender");
+				}
+			}
+		};
+
+		this.removeAppender = function(appender) {
+			array_remove(appenders, appender);
+			appender.setRemovedFromLogger(this);
+			this.invalidateAppenderCache();
+		};
+
+		this.removeAllAppenders = function() {
+			var appenderCount = appenders.length;
+			if (appenderCount > 0) {
+				for (var i = 0; i < appenderCount; i++) {
+					appenders[i].setRemovedFromLogger(this);
+				}
+				appenders.length = 0;
+				this.invalidateAppenderCache();
+			}
+		};
+
+		this.getEffectiveAppenders = function() {
+			if (appenderCache === null || appenderCacheInvalidated) {
+				// Build appender cache
+				var parentEffectiveAppenders = (isRoot || !this.getAdditivity()) ?
+					[] : this.parent.getEffectiveAppenders();
+				appenderCache = parentEffectiveAppenders.concat(appenders);
+				appenderCacheInvalidated = false;
+			}
+			return appenderCache;
+		};
+		
+		this.invalidateAppenderCache = function() {
+			appenderCacheInvalidated = true;
+			for (var i = 0, len = this.children.length; i < len; i++) {
+				this.children[i].invalidateAppenderCache();
+			}
+		};
+
+		this.log = function(level, params) {
+			if (enabled && level.isGreaterOrEqual(this.getEffectiveLevel())) {
+				// Check whether last param is an exception
+				var exception;
+				var finalParamIndex = params.length - 1;
+				var lastParam = params[finalParamIndex];
+				if (params.length > 1 && isError(lastParam)) {
+					exception = lastParam;
+					finalParamIndex--;
+				}
+
+				// Construct genuine array for the params
+				var messages = [];
+				for (var i = 0; i <= finalParamIndex; i++) {
+					messages[i] = params[i];
+				}
+
+				var loggingEvent = new LoggingEvent(
+					this, new Date(), level, messages, exception);
+
+				this.callAppenders(loggingEvent);
+			}
+		};
+
+		this.callAppenders = function(loggingEvent) {
+			var effectiveAppenders = this.getEffectiveAppenders();
+			for (var i = 0, len = effectiveAppenders.length; i < len; i++) {
+				effectiveAppenders[i].doAppend(loggingEvent);
+			}
+		};
+
+		this.setLevel = function(level) {
+			// Having a level of null on the root logger would be very bad.
+			if (isRoot && level === null) {
+				handleError("Logger.setLevel: you cannot set the level of the root logger to null");
+			} else if (level instanceof Level) {
+				loggerLevel = level;
+			} else {
+				handleError("Logger.setLevel: level supplied to logger " +
+					this.name + " is not an instance of log4javascript.Level");
+			}
+		};
+
+		this.getLevel = function() {
+			return loggerLevel;
+		};
+
+		this.getEffectiveLevel = function() {
+			for (var logger = this; logger !== null; logger = logger.parent) {
+				var level = logger.getLevel();
+				if (level !== null) {
+					return level;
+				}
+			}
+		};
+
+		this.group = function(name, initiallyExpanded) {
+			if (enabled) {
+				var effectiveAppenders = this.getEffectiveAppenders();
+				for (var i = 0, len = effectiveAppenders.length; i < len; i++) {
+					effectiveAppenders[i].group(name, initiallyExpanded);
+				}
+			}
+		};
+
+		this.groupEnd = function() {
+			if (enabled) {
+				var effectiveAppenders = this.getEffectiveAppenders();
+				for (var i = 0, len = effectiveAppenders.length; i < len; i++) {
+					effectiveAppenders[i].groupEnd();
+				}
+			}
+		};
+
+		var timers = {};
+
+		this.time = function(name, level) {
+			if (enabled) {
+				if (isUndefined(name)) {
+					handleError("Logger.time: a name for the timer must be supplied");
+				} else if (level && !(level instanceof Level)) {
+					handleError("Logger.time: level supplied to timer " +
+						name + " is not an instance of log4javascript.Level");
+				} else {
+					timers[name] = new Timer(name, level);
+				}
+			}
+		};
+
+		this.timeEnd = function(name) {
+			if (enabled) {
+				if (isUndefined(name)) {
+					handleError("Logger.timeEnd: a name for the timer must be supplied");
+				} else if (timers[name]) {
+					var timer = timers[name];
+					var milliseconds = timer.getElapsedTime();
+					this.log(timer.level, ["Timer " + toStr(name) + " completed in " + milliseconds + "ms"]);
+					delete timers[name];
+				} else {
+					logLog.warn("Logger.timeEnd: no timer found with name " + name);
+				}
+			}
+		};
+
+		this.assert = function(expr) {
+			if (enabled && !expr) {
+				var args = [];
+				for (var i = 1, len = arguments.length; i < len; i++) {
+					args.push(arguments[i]);
+				}
+				args = (args.length > 0) ? args : ["Assertion Failure"];
+				args.push(newLine);
+				args.push(expr);
+				this.log(Level.ERROR, args);
+			}
+		};
+
+		this.toString = function() {
+			return "Logger[" + this.name + "]";
+		};
+	}
+
+	Logger.prototype = {
+		trace: function() {
+			this.log(Level.TRACE, arguments);
+		},
+
+		debug: function() {
+			this.log(Level.DEBUG, arguments);
+		},
+
+		info: function() {
+			this.log(Level.INFO, arguments);
+		},
+
+		warn: function() {
+			this.log(Level.WARN, arguments);
+		},
+
+		error: function() {
+			this.log(Level.ERROR, arguments);
+		},
+
+		fatal: function() {
+			this.log(Level.FATAL, arguments);
+		},
+
+		isEnabledFor: function(level) {
+			return level.isGreaterOrEqual(this.getEffectiveLevel());
+		},
+
+		isTraceEnabled: function() {
+			return this.isEnabledFor(Level.TRACE);
+		},
+
+		isDebugEnabled: function() {
+			return this.isEnabledFor(Level.DEBUG);
+		},
+
+		isInfoEnabled: function() {
+			return this.isEnabledFor(Level.INFO);
+		},
+
+		isWarnEnabled: function() {
+			return this.isEnabledFor(Level.WARN);
+		},
+
+		isErrorEnabled: function() {
+			return this.isEnabledFor(Level.ERROR);
+		},
+
+		isFatalEnabled: function() {
+			return this.isEnabledFor(Level.FATAL);
+		}
+	};
+
+	Logger.prototype.trace.isEntryPoint = true;
+	Logger.prototype.debug.isEntryPoint = true;
+	Logger.prototype.info.isEntryPoint = true;
+	Logger.prototype.warn.isEntryPoint = true;
+	Logger.prototype.error.isEntryPoint = true;
+	Logger.prototype.fatal.isEntryPoint = true;
+
+	/* ---------------------------------------------------------------------- */
+	// Logger access methods
+
+	// Hashtable of loggers keyed by logger name
+	var loggers = {};
+	var loggerNames = [];
+
+	var ROOT_LOGGER_DEFAULT_LEVEL = Level.DEBUG;
+	var rootLogger = new Logger(rootLoggerName);
+	rootLogger.setLevel(ROOT_LOGGER_DEFAULT_LEVEL);
+
+	log4javascript.getRootLogger = function() {
+		return rootLogger;
+	};
+
+	log4javascript.getLogger = function(loggerName) {
+		// Use default logger if loggerName is not specified or invalid
+		if (!(typeof loggerName == "string")) {
+			loggerName = anonymousLoggerName;
+			logLog.warn("log4javascript.getLogger: non-string logger name "	+
+				toStr(loggerName) + " supplied, returning anonymous logger");
+		}
+
+		// Do not allow retrieval of the root logger by name
+		if (loggerName == rootLoggerName) {
+			handleError("log4javascript.getLogger: root logger may not be obtained by name");
+		}
+
+		// Create the logger for this name if it doesn't already exist
+		if (!loggers[loggerName]) {
+			var logger = new Logger(loggerName);
+			loggers[loggerName] = logger;
+			loggerNames.push(loggerName);
+
+			// Set up parent logger, if it doesn't exist
+			var lastDotIndex = loggerName.lastIndexOf(".");
+			var parentLogger;
+			if (lastDotIndex > -1) {
+				var parentLoggerName = loggerName.substring(0, lastDotIndex);
+				parentLogger = log4javascript.getLogger(parentLoggerName); // Recursively sets up grandparents etc.
+			} else {
+				parentLogger = rootLogger;
+			}
+			parentLogger.addChild(logger);
+		}
+		return loggers[loggerName];
+	};
+
+	var defaultLogger = null;
+	log4javascript.getDefaultLogger = function() {
+		if (!defaultLogger) {
+			defaultLogger = log4javascript.getLogger(defaultLoggerName);
+			var a = new log4javascript.PopUpAppender();
+			defaultLogger.addAppender(a);
+		}
+		return defaultLogger;
+	};
+
+	var nullLogger = null;
+	log4javascript.getNullLogger = function() {
+		if (!nullLogger) {
+			nullLogger = new Logger(nullLoggerName);
+			nullLogger.setLevel(Level.OFF);
+		}
+		return nullLogger;
+	};
+
+	// Destroys all loggers
+	log4javascript.resetConfiguration = function() {
+		rootLogger.setLevel(ROOT_LOGGER_DEFAULT_LEVEL);
+		loggers = {};
+	};
+
+	/* ---------------------------------------------------------------------- */
+	// Logging events
+
+	var LoggingEvent = function(logger, timeStamp, level, messages,
+			exception) {
+		this.logger = logger;
+		this.timeStamp = timeStamp;
+		this.timeStampInMilliseconds = timeStamp.getTime();
+		this.timeStampInSeconds = Math.floor(this.timeStampInMilliseconds / 1000);
+		this.milliseconds = this.timeStamp.getMilliseconds();
+		this.level = level;
+		this.messages = messages;
+		this.exception = exception;
+	};
+
+	LoggingEvent.prototype = {
+		getThrowableStrRep: function() {
+			return this.exception ?
+				getExceptionStringRep(this.exception) : "";
+		},
+		getCombinedMessages: function() {
+			return (this.messages.length == 1) ? this.messages[0] :
+				   this.messages.join(newLine);
+		},
+		toString: function() {
+			return "LoggingEvent[" + this.level + "]";
+		}
+	};
+
+	log4javascript.LoggingEvent = LoggingEvent;
+
+	/* ---------------------------------------------------------------------- */
+	// Layout prototype
+
+	var Layout = function() {
+	};
+
+	Layout.prototype = {
+		defaults: {
+			loggerKey: "logger",
+			timeStampKey: "timestamp",
+			millisecondsKey: "milliseconds",
+			levelKey: "level",
+			messageKey: "message",
+			exceptionKey: "exception",
+			urlKey: "url"
+		},
+		loggerKey: "logger",
+		timeStampKey: "timestamp",
+		millisecondsKey: "milliseconds",
+		levelKey: "level",
+		messageKey: "message",
+		exceptionKey: "exception",
+		urlKey: "url",
+		batchHeader: "",
+		batchFooter: "",
+		batchSeparator: "",
+		returnsPostData: false,
+		overrideTimeStampsSetting: false,
+		useTimeStampsInMilliseconds: null,
+
+		format: function() {
+			handleError("Layout.format: layout supplied has no format() method");
+		},
+
+		ignoresThrowable: function() {
+			handleError("Layout.ignoresThrowable: layout supplied has no ignoresThrowable() method");
+		},
+
+		getContentType: function() {
+			return "text/plain";
+		},
+
+		allowBatching: function() {
+			return true;
+		},
+
+		setTimeStampsInMilliseconds: function(timeStampsInMilliseconds) {
+			this.overrideTimeStampsSetting = true;
+			this.useTimeStampsInMilliseconds = bool(timeStampsInMilliseconds);
+		},
+
+		isTimeStampsInMilliseconds: function() {
+			return this.overrideTimeStampsSetting ?
+				this.useTimeStampsInMilliseconds : useTimeStampsInMilliseconds;
+		},
+
+		getTimeStampValue: function(loggingEvent) {
+			return this.isTimeStampsInMilliseconds() ?
+				loggingEvent.timeStampInMilliseconds : loggingEvent.timeStampInSeconds;
+		},
+
+		getDataValues: function(loggingEvent, combineMessages) {
+			var dataValues = [
+				[this.loggerKey, loggingEvent.logger.name],
+				[this.timeStampKey, this.getTimeStampValue(loggingEvent)],
+				[this.levelKey, loggingEvent.level.name],
+				[this.urlKey, window.location.href],
+				[this.messageKey, combineMessages ? loggingEvent.getCombinedMessages() : loggingEvent.messages]
+			];
+			if (!this.isTimeStampsInMilliseconds()) {
+				dataValues.push([this.millisecondsKey, loggingEvent.milliseconds]);
+			}
+			if (loggingEvent.exception) {
+				dataValues.push([this.exceptionKey, getExceptionStringRep(loggingEvent.exception)]);
+			}
+			if (this.hasCustomFields()) {
+				for (var i = 0, len = this.customFields.length; i < len; i++) {
+					var val = this.customFields[i].value;
+
+					// Check if the value is a function. If so, execute it, passing it the
+					// current layout and the logging event
+					if (typeof val === "function") {
+						val = val(this, loggingEvent);
+					}
+					dataValues.push([this.customFields[i].name, val]);
+				}
+			}
+			return dataValues;
+		},
+
+		setKeys: function(loggerKey, timeStampKey, levelKey, messageKey,
+				exceptionKey, urlKey, millisecondsKey) {
+			this.loggerKey = extractStringFromParam(loggerKey, this.defaults.loggerKey);
+			this.timeStampKey = extractStringFromParam(timeStampKey, this.defaults.timeStampKey);
+			this.levelKey = extractStringFromParam(levelKey, this.defaults.levelKey);
+			this.messageKey = extractStringFromParam(messageKey, this.defaults.messageKey);
+			this.exceptionKey = extractStringFromParam(exceptionKey, this.defaults.exceptionKey);
+			this.urlKey = extractStringFromParam(urlKey, this.defaults.urlKey);
+			this.millisecondsKey = extractStringFromParam(millisecondsKey, this.defaults.millisecondsKey);
+		},
+
+		setCustomField: function(name, value) {
+			var fieldUpdated = false;
+			for (var i = 0, len = this.customFields.length; i < len; i++) {
+				if (this.customFields[i].name === name) {
+					this.customFields[i].value = value;
+					fieldUpdated = true;
+				}
+			}
+			if (!fieldUpdated) {
+				this.customFields.push({"name": name, "value": value});
+			}
+		},
+
+		hasCustomFields: function() {
+			return (this.customFields.length > 0);
+		},
+
+		toString: function() {
+			handleError("Layout.toString: all layouts must override this method");
+		}
+	};
+
+	log4javascript.Layout = Layout;
+
+	/* ---------------------------------------------------------------------- */
+	// Appender prototype
+
+	var Appender = function() {};
+
+	Appender.prototype = new EventSupport();
+
+	Appender.prototype.layout = new PatternLayout();
+	Appender.prototype.threshold = Level.ALL;
+	Appender.prototype.loggers = [];
+
+	// Performs threshold checks before delegating actual logging to the
+	// subclass's specific append method.
+	Appender.prototype.doAppend = function(loggingEvent) {
+		if (enabled && loggingEvent.level.level >= this.threshold.level) {
+			this.append(loggingEvent);
+		}
+	};
+
+	Appender.prototype.append = function(loggingEvent) {};
+
+	Appender.prototype.setLayout = function(layout) {
+		if (layout instanceof Layout) {
+			this.layout = layout;
+		} else {
+			handleError("Appender.setLayout: layout supplied to " +
+				this.toString() + " is not a subclass of Layout");
+		}
+	};
+
+	Appender.prototype.getLayout = function() {
+		return this.layout;
+	};
+
+	Appender.prototype.setThreshold = function(threshold) {
+		if (threshold instanceof Level) {
+			this.threshold = threshold;
+		} else {
+			handleError("Appender.setThreshold: threshold supplied to " +
+				this.toString() + " is not a subclass of Level");
+		}
+	};
+
+	Appender.prototype.getThreshold = function() {
+		return this.threshold;
+	};
+
+	Appender.prototype.setAddedToLogger = function(logger) {
+		this.loggers.push(logger);
+	};
+
+	Appender.prototype.setRemovedFromLogger = function(logger) {
+		array_remove(this.loggers, logger);
+	};
+
+	Appender.prototype.group = emptyFunction;
+	Appender.prototype.groupEnd = emptyFunction;
+
+	Appender.prototype.toString = function() {
+		handleError("Appender.toString: all appenders must override this method");
+	};
+
+	log4javascript.Appender = Appender;
+
+	/* ---------------------------------------------------------------------- */
+	// SimpleLayout 
+
+	function SimpleLayout() {
+		this.customFields = [];
+	}
+
+	SimpleLayout.prototype = new Layout();
+
+	SimpleLayout.prototype.format = function(loggingEvent) {
+		return loggingEvent.level.name + " - " + loggingEvent.getCombinedMessages();
+	};
+
+	SimpleLayout.prototype.ignoresThrowable = function() {
+	    return true;
+	};
+
+	SimpleLayout.prototype.toString = function() {
+	    return "SimpleLayout";
+	};
+
+	log4javascript.SimpleLayout = SimpleLayout;
+	/* ----------------------------------------------------------------------- */
+	// NullLayout 
+
+	function NullLayout() {
+		this.customFields = [];
+	}
+
+	NullLayout.prototype = new Layout();
+
+	NullLayout.prototype.format = function(loggingEvent) {
+		return loggingEvent.messages;
+	};
+
+	NullLayout.prototype.ignoresThrowable = function() {
+	    return true;
+	};
+
+	NullLayout.prototype.toString = function() {
+	    return "NullLayout";
+	};
+
+	log4javascript.NullLayout = NullLayout;
+/* ---------------------------------------------------------------------- */
+	// XmlLayout
+
+	function XmlLayout(combineMessages) {
+		this.combineMessages = extractBooleanFromParam(combineMessages, true);
+		this.customFields = [];
+	}
+
+	XmlLayout.prototype = new Layout();
+
+	XmlLayout.prototype.isCombinedMessages = function() {
+		return this.combineMessages;
+	};
+
+	XmlLayout.prototype.getContentType = function() {
+		return "text/xml";
+	};
+
+	XmlLayout.prototype.escapeCdata = function(str) {
+		return str.replace(/\]\]>/, "]]>]]&gt;<![CDATA[");
+	};
+
+	XmlLayout.prototype.format = function(loggingEvent) {
+		var layout = this;
+		var i, len;
+		function formatMessage(message) {
+			message = (typeof message === "string") ? message : toStr(message);
+			return "<log4javascript:message><![CDATA[" +
+				layout.escapeCdata(message) + "]]></log4javascript:message>";
+		}
+
+		var str = "<log4javascript:event logger=\"" + loggingEvent.logger.name +
+			"\" timestamp=\"" + this.getTimeStampValue(loggingEvent) + "\"";
+		if (!this.isTimeStampsInMilliseconds()) {
+			str += " milliseconds=\"" + loggingEvent.milliseconds + "\"";
+		}
+		str += " level=\"" + loggingEvent.level.name + "\">" + newLine;
+		if (this.combineMessages) {
+			str += formatMessage(loggingEvent.getCombinedMessages());
+		} else {
+			str += "<log4javascript:messages>" + newLine;
+			for (i = 0, len = loggingEvent.messages.length; i < len; i++) {
+				str += formatMessage(loggingEvent.messages[i]) + newLine;
+			}
+			str += "</log4javascript:messages>" + newLine;
+		}
+		if (this.hasCustomFields()) {
+			for (i = 0, len = this.customFields.length; i < len; i++) {
+				str += "<log4javascript:customfield name=\"" +
+					this.customFields[i].name + "\"><![CDATA[" +
+					this.customFields[i].value.toString() +
+					"]]></log4javascript:customfield>" + newLine;
+			}
+		}
+		if (loggingEvent.exception) {
+			str += "<log4javascript:exception><![CDATA[" +
+				getExceptionStringRep(loggingEvent.exception) +
+				"]]></log4javascript:exception>" + newLine;
+		}
+		str += "</log4javascript:event>" + newLine + newLine;
+		return str;
+	};
+
+	XmlLayout.prototype.ignoresThrowable = function() {
+	    return false;
+	};
+
+	XmlLayout.prototype.toString = function() {
+	    return "XmlLayout";
+	};
+
+	log4javascript.XmlLayout = XmlLayout;
+	/* ---------------------------------------------------------------------- */
+	// JsonLayout related
+
+	function escapeNewLines(str) {
+		return str.replace(/\r\n|\r|\n/g, "\\r\\n");
+	}
+
+	function JsonLayout(readable, combineMessages) {
+		this.readable = extractBooleanFromParam(readable, false);
+		this.combineMessages = extractBooleanFromParam(combineMessages, true);
+		this.batchHeader = this.readable ? "[" + newLine : "[";
+		this.batchFooter = this.readable ? "]" + newLine : "]";
+		this.batchSeparator = this.readable ? "," + newLine : ",";
+		this.setKeys();
+		this.colon = this.readable ? ": " : ":";
+		this.tab = this.readable ? "\t" : "";
+		this.lineBreak = this.readable ? newLine : "";
+		this.customFields = [];
+	}
+
+	/* ---------------------------------------------------------------------- */
+	// JsonLayout
+
+	JsonLayout.prototype = new Layout();
+
+	JsonLayout.prototype.isReadable = function() {
+		return this.readable;
+	};
+
+	JsonLayout.prototype.isCombinedMessages = function() {
+		return this.combineMessages;
+	};
+
+    JsonLayout.prototype.format = function(loggingEvent) {
+        var layout = this;
+        var dataValues = this.getDataValues(loggingEvent, this.combineMessages);
+        var str = "{" + this.lineBreak;
+        var i, len;
+
+        function formatValue(val, prefix, expand) {
+            // Check the type of the data value to decide whether quotation marks
+            // or expansion are required
+            var formattedValue;
+            var valType = typeof val;
+            if (val instanceof Date) {
+                formattedValue = String(val.getTime());
+            } else if (expand && (val instanceof Array)) {
+                formattedValue = "[" + layout.lineBreak;
+                for (var i = 0, len = val.length; i < len; i++) {
+                    var childPrefix = prefix + layout.tab;
+                    formattedValue += childPrefix + formatValue(val[i], childPrefix, false);
+                    if (i < val.length - 1) {
+                        formattedValue += ",";
+                    }
+                    formattedValue += layout.lineBreak;
+                }
+                formattedValue += prefix + "]";
+            } else if (valType !== "number" && valType !== "boolean") {
+                formattedValue = "\"" + escapeNewLines(toStr(val).replace(/\"/g, "\\\"")) + "\"";
+            } else {
+                formattedValue = val;
+            }
+            return formattedValue;
+        }
+
+        for (i = 0, len = dataValues.length - 1; i <= len; i++) {
+            str += this.tab + "\"" + dataValues[i][0] + "\"" + this.colon + formatValue(dataValues[i][1], this.tab, true);
+            if (i < len) {
+                str += ",";
+            }
+            str += this.lineBreak;
+        }
+
+        str += "}" + this.lineBreak;
+        return str;
+    };
+
+	JsonLayout.prototype.ignoresThrowable = function() {
+	    return false;
+	};
+
+	JsonLayout.prototype.toString = function() {
+	    return "JsonLayout";
+	};
+
+	JsonLayout.prototype.getContentType = function() {
+		return "application/json";
+	};
+
+	log4javascript.JsonLayout = JsonLayout;
+	/* ---------------------------------------------------------------------- */
+	// HttpPostDataLayout
+
+	function HttpPostDataLayout() {
+		this.setKeys();
+		this.customFields = [];
+		this.returnsPostData = true;
+	}
+
+	HttpPostDataLayout.prototype = new Layout();
+
+	// Disable batching
+	HttpPostDataLayout.prototype.allowBatching = function() {
+		return false;
+	};
+
+	HttpPostDataLayout.prototype.format = function(loggingEvent) {
+		var dataValues = this.getDataValues(loggingEvent);
+		var queryBits = [];
+		for (var i = 0, len = dataValues.length; i < len; i++) {
+			var val = (dataValues[i][1] instanceof Date) ?
+				String(dataValues[i][1].getTime()) : dataValues[i][1];
+			queryBits.push(urlEncode(dataValues[i][0]) + "=" + urlEncode(val));
+		}
+		return queryBits.join("&");
+	};
+
+	HttpPostDataLayout.prototype.ignoresThrowable = function(loggingEvent) {
+	    return false;
+	};
+
+	HttpPostDataLayout.prototype.toString = function() {
+	    return "HttpPostDataLayout";
+	};
+
+	log4javascript.HttpPostDataLayout = HttpPostDataLayout;
+	/* ---------------------------------------------------------------------- */
+	// formatObjectExpansion
+
+	function formatObjectExpansion(obj, depth, indentation) {
+		var objectsExpanded = [];
+
+		function doFormat(obj, depth, indentation) {
+			var i, j, len, childDepth, childIndentation, childLines, expansion,
+				childExpansion;
+
+			if (!indentation) {
+				indentation = "";
+			}
+
+			function formatString(text) {
+				var lines = splitIntoLines(text);
+				for (var j = 1, jLen = lines.length; j < jLen; j++) {
+					lines[j] = indentation + lines[j];
+				}
+				return lines.join(newLine);
+			}
+
+			if (obj === null) {
+				return "null";
+			} else if (typeof obj == "undefined") {
+				return "undefined";
+			} else if (typeof obj == "string") {
+				return formatString(obj);
+			} else if (typeof obj == "object" && array_contains(objectsExpanded, obj)) {
+				try {
+					expansion = toStr(obj);
+				} catch (ex) {
+					expansion = "Error formatting property. Details: " + getExceptionStringRep(ex);
+				}
+				return expansion + " [already expanded]";
+			} else if ((obj instanceof Array) && depth > 0) {
+				objectsExpanded.push(obj);
+				expansion = "[" + newLine;
+				childDepth = depth - 1;
+				childIndentation = indentation + "  ";
+				childLines = [];
+				for (i = 0, len = obj.length; i < len; i++) {
+					try {
+						childExpansion = doFormat(obj[i], childDepth, childIndentation);
+						childLines.push(childIndentation + childExpansion);
+					} catch (ex) {
+						childLines.push(childIndentation + "Error formatting array member. Details: " +
+							getExceptionStringRep(ex) + "");
+					}
+				}
+				expansion += childLines.join("," + newLine) + newLine + indentation + "]";
+				return expansion;
+            } else if (Object.prototype.toString.call(obj) == "[object Date]") {
+                return obj.toString();
+			} else if (typeof obj == "object" && depth > 0) {
+				objectsExpanded.push(obj);
+				expansion = "{" + newLine;
+				childDepth = depth - 1;
+				childIndentation = indentation + "  ";
+				childLines = [];
+				for (i in obj) {
+					try {
+						childExpansion = doFormat(obj[i], childDepth, childIndentation);
+						childLines.push(childIndentation + i + ": " + childExpansion);
+					} catch (ex) {
+						childLines.push(childIndentation + i + ": Error formatting property. Details: " +
+							getExceptionStringRep(ex));
+					}
+				}
+				expansion += childLines.join("," + newLine) + newLine + indentation + "}";
+				return expansion;
+			} else {
+				return formatString(toStr(obj));
+			}
+		}
+		return doFormat(obj, depth, indentation);
+	}
+	/* ---------------------------------------------------------------------- */
+	// Date-related stuff
+
+	var SimpleDateFormat;
+
+	(function() {
+		var regex = /('[^']*')|(G+|y+|M+|w+|W+|D+|d+|F+|E+|a+|H+|k+|K+|h+|m+|s+|S+|Z+)|([a-zA-Z]+)|([^a-zA-Z']+)/;
+		var monthNames = ["January", "February", "March", "April", "May", "June",
+			"July", "August", "September", "October", "November", "December"];
+		var dayNames = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
+		var TEXT2 = 0, TEXT3 = 1, NUMBER = 2, YEAR = 3, MONTH = 4, TIMEZONE = 5;
+		var types = {
+			G : TEXT2,
+			y : YEAR,
+			M : MONTH,
+			w : NUMBER,
+			W : NUMBER,
+			D : NUMBER,
+			d : NUMBER,
+			F : NUMBER,
+			E : TEXT3,
+			a : TEXT2,
+			H : NUMBER,
+			k : NUMBER,
+			K : NUMBER,
+			h : NUMBER,
+			m : NUMBER,
+			s : NUMBER,
+			S : NUMBER,
+			Z : TIMEZONE
+		};
+		var ONE_DAY = 24 * 60 * 60 * 1000;
+		var ONE_WEEK = 7 * ONE_DAY;
+		var DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK = 1;
+
+		var newDateAtMidnight = function(year, month, day) {
+			var d = new Date(year, month, day, 0, 0, 0);
+			d.setMilliseconds(0);
+			return d;
+		};
+
+		Date.prototype.getDifference = function(date) {
+			return this.getTime() - date.getTime();
+		};
+
+		Date.prototype.isBefore = function(d) {
+			return this.getTime() < d.getTime();
+		};
+
+		Date.prototype.getUTCTime = function() {
+			return Date.UTC(this.getFullYear(), this.getMonth(), this.getDate(), this.getHours(), this.getMinutes(),
+					this.getSeconds(), this.getMilliseconds());
+		};
+
+		Date.prototype.getTimeSince = function(d) {
+			return this.getUTCTime() - d.getUTCTime();
+		};
+
+		Date.prototype.getPreviousSunday = function() {
+			// Using midday avoids any possibility of DST messing things up
+			var midday = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 12, 0, 0);
+			var previousSunday = new Date(midday.getTime() - this.getDay() * ONE_DAY);
+			return newDateAtMidnight(previousSunday.getFullYear(), previousSunday.getMonth(),
+					previousSunday.getDate());
+		};
+
+		Date.prototype.getWeekInYear = function(minimalDaysInFirstWeek) {
+			if (isUndefined(this.minimalDaysInFirstWeek)) {
+				minimalDaysInFirstWeek = DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK;
+			}
+			var previousSunday = this.getPreviousSunday();
+			var startOfYear = newDateAtMidnight(this.getFullYear(), 0, 1);
+			var numberOfSundays = previousSunday.isBefore(startOfYear) ?
+				0 : 1 + Math.floor(previousSunday.getTimeSince(startOfYear) / ONE_WEEK);
+			var numberOfDaysInFirstWeek =  7 - startOfYear.getDay();
+			var weekInYear = numberOfSundays;
+			if (numberOfDaysInFirstWeek < minimalDaysInFirstWeek) {
+				weekInYear--;
+			}
+			return weekInYear;
+		};
+
+		Date.prototype.getWeekInMonth = function(minimalDaysInFirstWeek) {
+			if (isUndefined(this.minimalDaysInFirstWeek)) {
+				minimalDaysInFirstWeek = DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK;
+			}
+			var previousSunday = this.getPreviousSunday();
+			var startOfMonth = newDateAtMidnight(this.getFullYear(), this.getMonth(), 1);
+			var numberOfSundays = previousSunday.isBefore(startOfMonth) ?
+				0 : 1 + Math.floor(previousSunday.getTimeSince(startOfMonth) / ONE_WEEK);
+			var numberOfDaysInFirstWeek =  7 - startOfMonth.getDay();
+			var weekInMonth = numberOfSundays;
+			if (numberOfDaysInFirstWeek >= minimalDaysInFirstWeek) {
+				weekInMonth++;
+			}
+			return weekInMonth;
+		};
+
+		Date.prototype.getDayInYear = function() {
+			var startOfYear = newDateAtMidnight(this.getFullYear(), 0, 1);
+			return 1 + Math.floor(this.getTimeSince(startOfYear) / ONE_DAY);
+		};
+
+		/* ------------------------------------------------------------------ */
+
+		SimpleDateFormat = function(formatString) {
+			this.formatString = formatString;
+		};
+
+		/**
+		 * Sets the minimum number of days in a week in order for that week to
+		 * be considered as belonging to a particular month or year
+		 */
+		SimpleDateFormat.prototype.setMinimalDaysInFirstWeek = function(days) {
+			this.minimalDaysInFirstWeek = days;
+		};
+
+		SimpleDateFormat.prototype.getMinimalDaysInFirstWeek = function() {
+			return isUndefined(this.minimalDaysInFirstWeek)	?
+				DEFAULT_MINIMAL_DAYS_IN_FIRST_WEEK : this.minimalDaysInFirstWeek;
+		};
+
+		var padWithZeroes = function(str, len) {
+			while (str.length < len) {
+				str = "0" + str;
+			}
+			return str;
+		};
+
+		var formatText = function(data, numberOfLetters, minLength) {
+			return (numberOfLetters >= 4) ? data : data.substr(0, Math.max(minLength, numberOfLetters));
+		};
+
+		var formatNumber = function(data, numberOfLetters) {
+			var dataString = "" + data;
+			// Pad with 0s as necessary
+			return padWithZeroes(dataString, numberOfLetters);
+		};
+
+		SimpleDateFormat.prototype.format = function(date) {
+			var formattedString = "";
+			var result;
+			var searchString = this.formatString;
+			while ((result = regex.exec(searchString))) {
+				var quotedString = result[1];
+				var patternLetters = result[2];
+				var otherLetters = result[3];
+				var otherCharacters = result[4];
+
+				// If the pattern matched is quoted string, output the text between the quotes
+				if (quotedString) {
+					if (quotedString == "''") {
+						formattedString += "'";
+					} else {
+						formattedString += quotedString.substring(1, quotedString.length - 1);
+					}
+				} else if (otherLetters) {
+					// Swallow non-pattern letters by doing nothing here
+				} else if (otherCharacters) {
+					// Simply output other characters
+					formattedString += otherCharacters;
+				} else if (patternLetters) {
+					// Replace pattern letters
+					var patternLetter = patternLetters.charAt(0);
+					var numberOfLetters = patternLetters.length;
+					var rawData = "";
+					switch(patternLetter) {
+						case "G":
+							rawData = "AD";
+							break;
+						case "y":
+							rawData = date.getFullYear();
+							break;
+						case "M":
+							rawData = date.getMonth();
+							break;
+						case "w":
+							rawData = date.getWeekInYear(this.getMinimalDaysInFirstWeek());
+							break;
+						case "W":
+							rawData = date.getWeekInMonth(this.getMinimalDaysInFirstWeek());
+							break;
+						case "D":
+							rawData = date.getDayInYear();
+							break;
+						case "d":
+							rawData = date.getDate();
+							break;
+						case "F":
+							rawData = 1 + Math.floor((date.getDate() - 1) / 7);
+							break;
+						case "E":
+							rawData = dayNames[date.getDay()];
+							break;
+						case "a":
+							rawData = (date.getHours() >= 12) ? "PM" : "AM";
+							break;
+						case "H":
+							rawData = date.getHours();
+							break;
+						case "k":
+							rawData = date.getHours() || 24;
+							break;
+						case "K":
+							rawData = date.getHours() % 12;
+							break;
+						case "h":
+							rawData = (date.getHours() % 12) || 12;
+							break;
+						case "m":
+							rawData = date.getMinutes();
+							break;
+						case "s":
+							rawData = date.getSeconds();
+							break;
+						case "S":
+							rawData = date.getMilliseconds();
+							break;
+						case "Z":
+							rawData = date.getTimezoneOffset(); // This returns the number of minutes since GMT was this time.
+							break;
+					}
+					// Format the raw data depending on the type
+					switch(types[patternLetter]) {
+						case TEXT2:
+							formattedString += formatText(rawData, numberOfLetters, 2);
+							break;
+						case TEXT3:
+							formattedString += formatText(rawData, numberOfLetters, 3);
+							break;
+						case NUMBER:
+							formattedString += formatNumber(rawData, numberOfLetters);
+							break;
+						case YEAR:
+							if (numberOfLetters <= 3) {
+								// Output a 2-digit year
+								var dataString = "" + rawData;
+								formattedString += dataString.substr(2, 2);
+							} else {
+								formattedString += formatNumber(rawData, numberOfLetters);
+							}
+							break;
+						case MONTH:
+							if (numberOfLetters >= 3) {
+								formattedString += formatText(monthNames[rawData], numberOfLetters, numberOfLetters);
+							} else {
+								// NB. Months returned by getMonth are zero-based
+								formattedString += formatNumber(rawData + 1, numberOfLetters);
+							}
+							break;
+						case TIMEZONE:
+							var isPositive = (rawData > 0);
+							// The following line looks like a mistake but isn't
+							// because of the way getTimezoneOffset measures.
+							var prefix = isPositive ? "-" : "+";
+							var absData = Math.abs(rawData);
+
+							// Hours
+							var hours = "" + Math.floor(absData / 60);
+							hours = padWithZeroes(hours, 2);
+							// Minutes
+							var minutes = "" + (absData % 60);
+							minutes = padWithZeroes(minutes, 2);
+
+							formattedString += prefix + hours + minutes;
+							break;
+					}
+				}
+				searchString = searchString.substr(result.index + result[0].length);
+			}
+			return formattedString;
+		};
+	})();
+
+	log4javascript.SimpleDateFormat = SimpleDateFormat;
+
+	/* ---------------------------------------------------------------------- */
+	// PatternLayout
+
+	function PatternLayout(pattern) {
+		if (pattern) {
+			this.pattern = pattern;
+		} else {
+			this.pattern = PatternLayout.DEFAULT_CONVERSION_PATTERN;
+		}
+		this.customFields = [];
+	}
+
+	PatternLayout.TTCC_CONVERSION_PATTERN = "%r %p %c - %m%n";
+	PatternLayout.DEFAULT_CONVERSION_PATTERN = "%m%n";
+	PatternLayout.ISO8601_DATEFORMAT = "yyyy-MM-dd HH:mm:ss,SSS";
+	PatternLayout.DATETIME_DATEFORMAT = "dd MMM yyyy HH:mm:ss,SSS";
+	PatternLayout.ABSOLUTETIME_DATEFORMAT = "HH:mm:ss,SSS";
+
+	PatternLayout.prototype = new Layout();
+
+	PatternLayout.prototype.format = function(loggingEvent) {
+		var regex = /%(-?[0-9]+)?(\.?[0-9]+)?([acdfmMnpr%])(\{([^\}]+)\})?|([^%]+)/;
+		var formattedString = "";
+		var result;
+		var searchString = this.pattern;
+
+		// Cannot use regex global flag since it doesn't work with exec in IE5
+		while ((result = regex.exec(searchString))) {
+			var matchedString = result[0];
+			var padding = result[1];
+			var truncation = result[2];
+			var conversionCharacter = result[3];
+			var specifier = result[5];
+			var text = result[6];
+
+			// Check if the pattern matched was just normal text
+			if (text) {
+				formattedString += "" + text;
+			} else {
+				// Create a raw replacement string based on the conversion
+				// character and specifier
+				var replacement = "";
+				switch(conversionCharacter) {
+					case "a": // Array of messages
+					case "m": // Message
+						var depth = 0;
+						if (specifier) {
+							depth = parseInt(specifier, 10);
+							if (isNaN(depth)) {
+								handleError("PatternLayout.format: invalid specifier '" +
+									specifier + "' for conversion character '" + conversionCharacter +
+									"' - should be a number");
+								depth = 0;
+							}
+						}
+						var messages = (conversionCharacter === "a") ? loggingEvent.messages[0] : loggingEvent.messages;
+						for (var i = 0, len = messages.length; i < len; i++) {
+							if (i > 0 && (replacement.charAt(replacement.length - 1) !== " ")) {
+								replacement += " ";
+							}
+							if (depth === 0) {
+								replacement += messages[i];
+							} else {
+								replacement += formatObjectExpansion(messages[i], depth);
+							}
+						}
+						break;
+					case "c": // Logger name
+						var loggerName = loggingEvent.logger.name;
+						if (specifier) {
+							var precision = parseInt(specifier, 10);
+							var loggerNameBits = loggingEvent.logger.name.split(".");
+							if (precision >= loggerNameBits.length) {
+								replacement = loggerName;
+							} else {
+								replacement = loggerNameBits.slice(loggerNameBits.length - precision).join(".");
+							}
+						} else {
+							replacement = loggerName;
+						}
+						break;
+					case "d": // Date
+						var dateFormat = PatternLayout.ISO8601_DATEFORMAT;
+						if (specifier) {
+							dateFormat = specifier;
+							// Pick up special cases
+							if (dateFormat == "ISO8601") {
+								dateFormat = PatternLayout.ISO8601_DATEFORMAT;
+							} else if (dateFormat == "ABSOLUTE") {
+								dateFormat = PatternLayout.ABSOLUTETIME_DATEFORMAT;
+							} else if (dateFormat == "DATE") {
+								dateFormat = PatternLayout.DATETIME_DATEFORMAT;
+							}
+						}
+						// Format the date
+						replacement = (new SimpleDateFormat(dateFormat)).format(loggingEvent.timeStamp);
+						break;
+					case "f": // Custom field
+						if (this.hasCustomFields()) {
+							var fieldIndex = 0;
+							if (specifier) {
+								fieldIndex = parseInt(specifier, 10);
+								if (isNaN(fieldIndex)) {
+									handleError("PatternLayout.format: invalid specifier '" +
+										specifier + "' for conversion character 'f' - should be a number");
+								} else if (fieldIndex === 0) {
+									handleError("PatternLayout.format: invalid specifier '" +
+										specifier + "' for conversion character 'f' - must be greater than zero");
+								} else if (fieldIndex > this.customFields.length) {
+									handleError("PatternLayout.format: invalid specifier '" +
+										specifier + "' for conversion character 'f' - there aren't that many custom fields");
+								} else {
+									fieldIndex = fieldIndex - 1;
+								}
+							}
+                            var val = this.customFields[fieldIndex].value;
+                            if (typeof val == "function") {
+                                val = val(this, loggingEvent);
+                            }
+                            replacement = val;
+						}
+						break;
+					case "n": // New line
+						replacement = newLine;
+						break;
+					case "p": // Level
+						replacement = loggingEvent.level.name;
+						break;
+					case "r": // Milliseconds since log4javascript startup
+						replacement = "" + loggingEvent.timeStamp.getDifference(applicationStartDate);
+						break;
+					case "%": // Literal % sign
+						replacement = "%";
+						break;
+					default:
+						replacement = matchedString;
+						break;
+				}
+				// Format the replacement according to any padding or
+				// truncation specified
+				var l;
+
+				// First, truncation
+				if (truncation) {
+					l = parseInt(truncation.substr(1), 10);
+					var strLen = replacement.length;
+					if (l < strLen) {
+						replacement = replacement.substring(strLen - l, strLen);
+					}
+				}
+				// Next, padding
+				if (padding) {
+					if (padding.charAt(0) == "-") {
+						l = parseInt(padding.substr(1), 10);
+						// Right pad with spaces
+						while (replacement.length < l) {
+							replacement += " ";
+						}
+					} else {
+						l = parseInt(padding, 10);
+						// Left pad with spaces
+						while (replacement.length < l) {
+							replacement = " " + replacement;
+						}
+					}
+				}
+				formattedString += replacement;
+			}
+			searchString = searchString.substr(result.index + result[0].length);
+		}
+		return formattedString;
+	};
+
+	PatternLayout.prototype.ignoresThrowable = function() {
+	    return true;
+	};
+
+	PatternLayout.prototype.toString = function() {
+	    return "PatternLayout";
+	};
+
+	log4javascript.PatternLayout = PatternLayout;
+	/* ---------------------------------------------------------------------- */
+	// AlertAppender
+
+	function AlertAppender() {}
+
+	AlertAppender.prototype = new Appender();
+
+	AlertAppender.prototype.layout = new SimpleLayout();
+
+	AlertAppender.prototype.append = function(loggingEvent) {
+		var formattedMessage = this.getLayout().format(loggingEvent);
+		if (this.getLayout().ignoresThrowable()) {
+			formattedMessage += loggingEvent.getThrowableStrRep();
+		}
+		alert(formattedMessage);
+	};
+
+	AlertAppender.prototype.toString = function() {
+		return "AlertAppender";
+	};
+
+	log4javascript.AlertAppender = AlertAppender;
+	/* ---------------------------------------------------------------------- */
+	// BrowserConsoleAppender (only works in Opera and Safari and Firefox with
+	// Firebug extension)
+
+	function BrowserConsoleAppender() {}
+
+	BrowserConsoleAppender.prototype = new log4javascript.Appender();
+	BrowserConsoleAppender.prototype.layout = new NullLayout();
+	BrowserConsoleAppender.prototype.threshold = Level.DEBUG;
+
+	BrowserConsoleAppender.prototype.append = function(loggingEvent) {
+		var appender = this;
+
+		var getFormattedMessage = function() {
+			var layout = appender.getLayout();
+			var formattedMessage = layout.format(loggingEvent);
+			if (layout.ignoresThrowable() && loggingEvent.exception) {
+				formattedMessage += loggingEvent.getThrowableStrRep();
+			}
+			return formattedMessage;
+		};
+
+		if ((typeof opera != "undefined") && opera.postError) { // Opera
+			opera.postError(getFormattedMessage());
+		} else if (window.console && window.console.log) { // Safari and Firebug
+			var formattedMesage = getFormattedMessage();
+			// Log to Firebug using its logging methods or revert to the console.log
+			// method in Safari
+			if (window.console.debug && Level.DEBUG.isGreaterOrEqual(loggingEvent.level)) {
+				window.console.debug(formattedMesage);
+			} else if (window.console.info && Level.INFO.equals(loggingEvent.level)) {
+				window.console.info(formattedMesage);
+			} else if (window.console.warn && Level.WARN.equals(loggingEvent.level)) {
+				window.console.warn(formattedMesage);
+			} else if (window.console.error && loggingEvent.level.isGreaterOrEqual(Level.ERROR)) {
+				window.console.error(formattedMesage);
+			} else {
+				window.console.log(formattedMesage);
+			}
+		}
+	};
+
+	BrowserConsoleAppender.prototype.group = function(name) {
+		if (window.console && window.console.group) {
+			window.console.group(name);
+		}
+	};
+
+	BrowserConsoleAppender.prototype.groupEnd = function() {
+		if (window.console && window.console.groupEnd) {
+			window.console.groupEnd();
+		}
+	};
+
+	BrowserConsoleAppender.prototype.toString = function() {
+		return "BrowserConsoleAppender";
+	};
+
+	log4javascript.BrowserConsoleAppender = BrowserConsoleAppender;
+	/* ---------------------------------------------------------------------- */
+	// AjaxAppender related
+
+	var xmlHttpFactories = [
+		function() { return new XMLHttpRequest(); },
+		function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
+		function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
+	];
+
+	var getXmlHttp = function(errorHandler) {
+		// This is only run the first time; the value of getXmlHttp gets
+		// replaced with the factory that succeeds on the first run
+		var xmlHttp = null, factory;
+		for (var i = 0, len = xmlHttpFactories.length; i < len; i++) {
+			factory = xmlHttpFactories[i];
+			try {
+				xmlHttp = factory();
+				getXmlHttp = factory;
+				return xmlHttp;
+			} catch (e) {
+			}
+		}
+		// If we're here, all factories have failed, so throw an error
+		if (errorHandler) {
+			errorHandler();
+		} else {
+			handleError("getXmlHttp: unable to obtain XMLHttpRequest object");
+		}
+	};
+
+	function isHttpRequestSuccessful(xmlHttp) {
+		return isUndefined(xmlHttp.status) || xmlHttp.status === 0 ||
+			(xmlHttp.status >= 200 && xmlHttp.status < 300) ||
+			xmlHttp.status == 1223 /* Fix for IE */;
+	}
+
+	/* ---------------------------------------------------------------------- */
+	// AjaxAppender
+
+	function AjaxAppender(url) {
+		var appender = this;
+		var isSupported = true;
+		if (!url) {
+			handleError("AjaxAppender: URL must be specified in constructor");
+			isSupported = false;
+		}
+
+		var timed = this.defaults.timed;
+		var waitForResponse = this.defaults.waitForResponse;
+		var batchSize = this.defaults.batchSize;
+		var timerInterval = this.defaults.timerInterval;
+		var requestSuccessCallback = this.defaults.requestSuccessCallback;
+		var failCallback = this.defaults.failCallback;
+		var postVarName = this.defaults.postVarName;
+		var sendAllOnUnload = this.defaults.sendAllOnUnload;
+		var contentType = this.defaults.contentType;
+		var sessionId = null;
+
+		var queuedLoggingEvents = [];
+		var queuedRequests = [];
+		var headers = [];
+		var sending = false;
+		var initialized = false;
+
+		// Configuration methods. The function scope is used to prevent
+		// direct alteration to the appender configuration properties.
+		function checkCanConfigure(configOptionName) {
+			if (initialized) {
+				handleError("AjaxAppender: configuration option '" +
+					configOptionName +
+					"' may not be set after the appender has been initialized");
+				return false;
+			}
+			return true;
+		}
+
+		this.getSessionId = function() { return sessionId; };
+		this.setSessionId = function(sessionIdParam) {
+			sessionId = extractStringFromParam(sessionIdParam, null);
+			this.layout.setCustomField("sessionid", sessionId);
+		};
+
+		this.setLayout = function(layoutParam) {
+			if (checkCanConfigure("layout")) {
+				this.layout = layoutParam;
+				// Set the session id as a custom field on the layout, if not already present
+				if (sessionId !== null) {
+					this.setSessionId(sessionId);
+				}
+			}
+		};
+
+		this.isTimed = function() { return timed; };
+		this.setTimed = function(timedParam) {
+			if (checkCanConfigure("timed")) {
+				timed = bool(timedParam);
+			}
+		};
+
+		this.getTimerInterval = function() { return timerInterval; };
+		this.setTimerInterval = function(timerIntervalParam) {
+			if (checkCanConfigure("timerInterval")) {
+				timerInterval = extractIntFromParam(timerIntervalParam, timerInterval);
+			}
+		};
+
+		this.isWaitForResponse = function() { return waitForResponse; };
+		this.setWaitForResponse = function(waitForResponseParam) {
+			if (checkCanConfigure("waitForResponse")) {
+				waitForResponse = bool(waitForResponseParam);
+			}
+		};
+
+		this.getBatchSize = function() { return batchSize; };
+		this.setBatchSize = function(batchSizeParam) {
+			if (checkCanConfigure("batchSize")) {
+				batchSize = extractIntFromParam(batchSizeParam, batchSize);
+			}
+		};
+
+		this.isSendAllOnUnload = function() { return sendAllOnUnload; };
+		this.setSendAllOnUnload = function(sendAllOnUnloadParam) {
+			if (checkCanConfigure("sendAllOnUnload")) {
+				sendAllOnUnload = extractBooleanFromParam(sendAllOnUnloadParam, sendAllOnUnload);
+			}
+		};
+
+		this.setRequestSuccessCallback = function(requestSuccessCallbackParam) {
+			requestSuccessCallback = extractFunctionFromParam(requestSuccessCallbackParam, requestSuccessCallback);
+		};
+
+		this.setFailCallback = function(failCallbackParam) {
+			failCallback = extractFunctionFromParam(failCallbackParam, failCallback);
+		};
+
+		this.getPostVarName = function() { return postVarName; };
+		this.setPostVarName = function(postVarNameParam) {
+			if (checkCanConfigure("postVarName")) {
+				postVarName = extractStringFromParam(postVarNameParam, postVarName);
+			}
+		};
+
+		this.getHeaders = function() { return headers; };
+		this.addHeader = function(name, value) {
+			if (name.toLowerCase() == "content-type") {
+				contentType = value;
+			} else {
+				headers.push( { name: name, value: value } );
+			}
+		};
+
+		// Internal functions
+		function sendAll() {
+			if (isSupported && enabled) {
+				sending = true;
+				var currentRequestBatch;
+				if (waitForResponse) {
+					// Send the first request then use this function as the callback once
+					// the response comes back
+					if (queuedRequests.length > 0) {
+						currentRequestBatch = queuedRequests.shift();
+						sendRequest(preparePostData(currentRequestBatch), sendAll);
+					} else {
+						sending = false;
+						if (timed) {
+							scheduleSending();
+						}
+					}
+				} else {
+					// Rattle off all the requests without waiting to see the response
+					while ((currentRequestBatch = queuedRequests.shift())) {
+						sendRequest(preparePostData(currentRequestBatch));
+					}
+					sending = false;
+					if (timed) {
+						scheduleSending();
+					}
+				}
+			}
+		}
+
+		this.sendAll = sendAll;
+
+		// Called when the window unloads. At this point we're past caring about
+		// waiting for responses or timers or incomplete batches - everything
+		// must go, now
+		function sendAllRemaining() {
+			var sendingAnything = false;
+			if (isSupported && enabled) {
+				// Create requests for everything left over, batched as normal
+				var actualBatchSize = appender.getLayout().allowBatching() ? batchSize : 1;
+				var currentLoggingEvent;
+				var batchedLoggingEvents = [];
+				while ((currentLoggingEvent = queuedLoggingEvents.shift())) {
+					batchedLoggingEvents.push(currentLoggingEvent);
+					if (queuedLoggingEvents.length >= actualBatchSize) {
+						// Queue this batch of log entries
+						queuedRequests.push(batchedLoggingEvents);
+						batchedLoggingEvents = [];
+					}
+				}
+				// If there's a partially completed batch, add it
+				if (batchedLoggingEvents.length > 0) {
+					queuedRequests.push(batchedLoggingEvents);
+				}
+				sendingAnything = (queuedRequests.length > 0);
+				waitForResponse = false;
+				timed = false;
+				sendAll();
+			}
+			return sendingAnything;
+		}
+
+		this.sendAllRemaining = sendAllRemaining;
+
+		function preparePostData(batchedLoggingEvents) {
+			// Format the logging events
+			var formattedMessages = [];
+			var currentLoggingEvent;
+			var postData = "";
+			while ((currentLoggingEvent = batchedLoggingEvents.shift())) {
+				var currentFormattedMessage = appender.getLayout().format(currentLoggingEvent);
+				if (appender.getLayout().ignoresThrowable()) {
+					currentFormattedMessage += currentLoggingEvent.getThrowableStrRep();
+				}
+				formattedMessages.push(currentFormattedMessage);
+			}
+			// Create the post data string
+			if (batchedLoggingEvents.length == 1) {
+				postData = formattedMessages.join("");
+			} else {
+				postData = appender.getLayout().batchHeader +
+					formattedMessages.join(appender.getLayout().batchSeparator) +
+					appender.getLayout().batchFooter;
+			}
+			if (contentType == appender.defaults.contentType) {
+				postData = appender.getLayout().returnsPostData ? postData :
+					urlEncode(postVarName) + "=" + urlEncode(postData);
+				// Add the layout name to the post data
+				if (postData.length > 0) {
+					postData += "&";
+				}
+				postData += "layout=" + urlEncode(appender.getLayout().toString());
+			}
+			return postData;
+		}
+
+		function scheduleSending() {
+			window.setTimeout(sendAll, timerInterval);
+		}
+
+		function xmlHttpErrorHandler() {
+			var msg = "AjaxAppender: could not create XMLHttpRequest object. AjaxAppender disabled";
+			handleError(msg);
+			isSupported = false;
+			if (failCallback) {
+				failCallback(msg);
+			}
+		}
+
+		function sendRequest(postData, successCallback) {
+			try {
+				var xmlHttp = getXmlHttp(xmlHttpErrorHandler);
+				if (isSupported) {
+					if (xmlHttp.overrideMimeType) {
+						xmlHttp.overrideMimeType(appender.getLayout().getContentType());
+					}
+					xmlHttp.onreadystatechange = function() {
+						if (xmlHttp.readyState == 4) {
+							if (isHttpRequestSuccessful(xmlHttp)) {
+								if (requestSuccessCallback) {
+									requestSuccessCallback(xmlHttp);
+								}
+								if (successCallback) {
+									successCallback(xmlHttp);
+								}
+							} else {
+								var msg = "AjaxAppender.append: XMLHttpRequest request to URL " +
+									url + " returned status code " + xmlHttp.status;
+								handleError(msg);
+								if (failCallback) {
+									failCallback(msg);
+								}
+							}
+							xmlHttp.onreadystatechange = emptyFunction;
+							xmlHttp = null;
+						}
+					};
+					xmlHttp.open("POST", url, true);
+					try {
+						for (var i = 0, header; header = headers[i++]; ) {
+							xmlHttp.setRequestHeader(header.name, header.value);
+						}
+						xmlHttp.setRequestHeader("Content-Type", contentType);
+					} catch (headerEx) {
+						var msg = "AjaxAppender.append: your browser's XMLHttpRequest implementation" +
+							" does not support setRequestHeader, therefore cannot post data. AjaxAppender disabled";
+						handleError(msg);
+						isSupported = false;
+						if (failCallback) {
+							failCallback(msg);
+						}
+						return;
+					}
+					xmlHttp.send(postData);
+				}
+			} catch (ex) {
+				var errMsg = "AjaxAppender.append: error sending log message to " + url;
+				handleError(errMsg, ex);
+				isSupported = false;
+				if (failCallback) {
+					failCallback(errMsg + ". Details: " + getExceptionStringRep(ex));
+				}
+			}
+		}
+
+		this.append = function(loggingEvent) {
+			if (isSupported) {
+				if (!initialized) {
+					init();
+				}
+				queuedLoggingEvents.push(loggingEvent);
+				var actualBatchSize = this.getLayout().allowBatching() ? batchSize : 1;
+
+				if (queuedLoggingEvents.length >= actualBatchSize) {
+					var currentLoggingEvent;
+					var batchedLoggingEvents = [];
+					while ((currentLoggingEvent = queuedLoggingEvents.shift())) {
+						batchedLoggingEvents.push(currentLoggingEvent);
+					}
+					// Queue this batch of log entries
+					queuedRequests.push(batchedLoggingEvents);
+
+					// If using a timer, the queue of requests will be processed by the
+					// timer function, so nothing needs to be done here.
+					if (!timed && (!waitForResponse || (waitForResponse && !sending))) {
+						sendAll();
+					}
+				}
+			}
+		};
+
+		function init() {
+			initialized = true;
+			// Add unload event to send outstanding messages
+			if (sendAllOnUnload) {
+				var oldBeforeUnload = window.onbeforeunload;
+				window.onbeforeunload = function() {
+					if (oldBeforeUnload) {
+						oldBeforeUnload();
+					}
+					if (sendAllRemaining()) {
+						return "Sending log messages";
+					}
+				};
+			}
+			// Start timer
+			if (timed) {
+				scheduleSending();
+			}
+		}
+	}
+
+	AjaxAppender.prototype = new Appender();
+
+	AjaxAppender.prototype.defaults = {
+		waitForResponse: false,
+		timed: false,
+		timerInterval: 1000,
+		batchSize: 1,
+		sendAllOnUnload: false,
+		requestSuccessCallback: null,
+		failCallback: null,
+		postVarName: "data",
+		contentType: "application/x-www-form-urlencoded"
+	};
+
+	AjaxAppender.prototype.layout = new HttpPostDataLayout();
+
+	AjaxAppender.prototype.toString = function() {
+		return "AjaxAppender";
+	};
+
+	log4javascript.AjaxAppender = AjaxAppender;
+	/* ---------------------------------------------------------------------- */
+	// PopUpAppender and InPageAppender related
+
+	function setCookie(name, value, days, path) {
+	    var expires;
+	    path = path ? "; path=" + path : "";
+		if (days) {
+			var date = new Date();
+			date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
+			expires = "; expires=" + date.toGMTString();
+		} else {
+		    expires = "";
+	    }
+		document.cookie = escape(name) + "=" + escape(value) + expires + path;
+	}
+
+	function getCookie(name) {
+		var nameEquals = escape(name) + "=";
+		var ca = document.cookie.split(";");
+		for (var i = 0, len = ca.length; i < len; i++) {
+			var c = ca[i];
+			while (c.charAt(0) === " ") {
+			    c = c.substring(1, c.length);
+			}
+			if (c.indexOf(nameEquals) === 0) {
+			    return unescape(c.substring(nameEquals.length, c.length));
+	        }
+		}
+		return null;
+	}
+
+	// Gets the base URL of the location of the log4javascript script.
+	// This is far from infallible.
+	function getBaseUrl() {
+		var scripts = document.getElementsByTagName("script");
+		for (var i = 0, len = scripts.length; i < len; ++i) {
+			if (scripts[i].src.indexOf("log4javascript") != -1) {
+				var lastSlash = scripts[i].src.lastIndexOf("/");
+				return (lastSlash == -1) ? "" : scripts[i].src.substr(0, lastSlash + 1);
+			}
+		}
+        return null;
+    }
+
+	function isLoaded(win) {
+		try {
+			return bool(win.loaded);
+		} catch (ex) {
+			return false;
+		}
+	}
+
+	/* ---------------------------------------------------------------------- */
+	// ConsoleAppender (prototype for PopUpAppender and InPageAppender)
+
+	var ConsoleAppender;
+
+	// Create an anonymous function to protect base console methods
+	(function() {
+		var getConsoleHtmlLines = function() {
+			return [
+'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">',
+'<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">',
+'	<head>',
+'		<title>log4javascript</title>',
+'		<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />',
+'		<!-- Make IE8 behave like IE7, having gone to all the trouble of making IE work -->',
+'		<meta http-equiv="X-UA-Compatible" content="IE=7" />',
+'		<script type="text/javascript">var isIe = false, isIePre7 = false;</script>',
+'		<!--[if IE]><script type="text/javascript">isIe = true</script><![endif]-->',
+'		<!--[if lt IE 7]><script type="text/javascript">isIePre7 = true</script><![endif]-->',
+'		<script type="text/javascript">',
+'			//<![CDATA[',
+'			var loggingEnabled = true;',
+'			var logQueuedEventsTimer = null;',
+'			var logEntries = [];',
+'			var logEntriesAndSeparators = [];',
+'			var logItems = [];',
+'			var renderDelay = 100;',
+'			var unrenderedLogItemsExist = false;',
+'			var rootGroup, currentGroup = null;',
+'			var loaded = false;',
+'			var currentLogItem = null;',
+'			var logMainContainer;',
+'',
+'			function copyProperties(obj, props) {',
+'				for (var i in props) {',
+'					obj[i] = props[i];',
+'				}',
+'			}',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function LogItem() {',
+'			}',
+'',
+'			LogItem.prototype = {',
+'				mainContainer: null,',
+'				wrappedContainer: null,',
+'				unwrappedContainer: null,',
+'				group: null,',
+'',
+'				appendToLog: function() {',
+'					for (var i = 0, len = this.elementContainers.length; i < len; i++) {',
+'						this.elementContainers[i].appendToLog();',
+'					}',
+'					this.group.update();',
+'				},',
+'',
+'				doRemove: function(doUpdate, removeFromGroup) {',
+'					if (this.rendered) {',
+'						for (var i = 0, len = this.elementContainers.length; i < len; i++) {',
+'							this.elementContainers[i].remove();',
+'						}',
+'						this.unwrappedElementContainer = null;',
+'						this.wrappedElementContainer = null;',
+'						this.mainElementContainer = null;',
+'					}',
+'					if (this.group && removeFromGroup) {',
+'						this.group.removeChild(this, doUpdate);',
+'					}',
+'					if (this === currentLogItem) {',
+'						currentLogItem = null;',
+'					}',
+'				},',
+'',
+'				remove: function(doUpdate, removeFromGroup) {',
+'					this.doRemove(doUpdate, removeFromGroup);',
+'				},',
+'',
+'				render: function() {},',
+'',
+'				accept: function(visitor) {',
+'					visitor.visit(this);',
+'				},',
+'',
+'				getUnwrappedDomContainer: function() {',
+'					return this.group.unwrappedElementContainer.contentDiv;',
+'				},',
+'',
+'				getWrappedDomContainer: function() {',
+'					return this.group.wrappedElementContainer.contentDiv;',
+'				},',
+'',
+'				getMainDomContainer: function() {',
+'					return this.group.mainElementContainer.contentDiv;',
+'				}',
+'			};',
+'',
+'			LogItem.serializedItemKeys = {LOG_ENTRY: 0, GROUP_START: 1, GROUP_END: 2};',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function LogItemContainerElement() {',
+'			}',
+'',
+'			LogItemContainerElement.prototype = {',
+'				appendToLog: function() {',
+'					var insertBeforeFirst = (newestAtTop && this.containerDomNode.hasChildNodes());',
+'					if (insertBeforeFirst) {',
+'						this.containerDomNode.insertBefore(this.mainDiv, this.containerDomNode.firstChild);',
+'					} else {',
+'						this.containerDomNode.appendChild(this.mainDiv);',
+'					}',
+'				}',
+'			};',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function SeparatorElementContainer(containerDomNode) {',
+'				this.containerDomNode = containerDomNode;',
+'				this.mainDiv = document.createElement("div");',
+'				this.mainDiv.className = "separator";',
+'				this.mainDiv.innerHTML = "&nbsp;";',
+'			}',
+'',
+'			SeparatorElementContainer.prototype = new LogItemContainerElement();',
+'',
+'			SeparatorElementContainer.prototype.remove = function() {',
+'				this.mainDiv.parentNode.removeChild(this.mainDiv);',
+'				this.mainDiv = null;',
+'			};',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function Separator() {',
+'				this.rendered = false;',
+'			}',
+'',
+'			Separator.prototype = new LogItem();',
+'',
+'			copyProperties(Separator.prototype, {',
+'				render: function() {',
+'					var containerDomNode = this.group.contentDiv;',
+'					if (isIe) {',
+'						this.unwrappedElementContainer = new SeparatorElementContainer(this.getUnwrappedDomContainer());',
+'						this.wrappedElementContainer = new SeparatorElementContainer(this.getWrappedDomContainer());',
+'						this.elementContainers = [this.unwrappedElementContainer, this.wrappedElementContainer];',
+'					} else {',
+'						this.mainElementContainer = new SeparatorElementContainer(this.getMainDomContainer());',
+'						this.elementContainers = [this.mainElementContainer];',
+'					}',
+'					this.content = this.formattedMessage;',
+'					this.rendered = true;',
+'				}',
+'			});',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function GroupElementContainer(group, containerDomNode, isRoot, isWrapped) {',
+'				this.group = group;',
+'				this.containerDomNode = containerDomNode;',
+'				this.isRoot = isRoot;',
+'				this.isWrapped = isWrapped;',
+'				this.expandable = false;',
+'',
+'				if (this.isRoot) {',
+'					if (isIe) {',
+'						this.contentDiv = logMainContainer.appendChild(document.createElement("div"));',
+'						this.contentDiv.id = this.isWrapped ? "log_wrapped" : "log_unwrapped";',
+'					} else {',
+'						this.contentDiv = logMainContainer;',
+'					}',
+'				} else {',
+'					var groupElementContainer = this;',
+'					',
+'					this.mainDiv = document.createElement("div");',
+'					this.mainDiv.className = "group";',
+'',
+'					this.headingDiv = this.mainDiv.appendChild(document.createElement("div"));',
+'					this.headingDiv.className = "groupheading";',
+'',
+'					this.expander = this.headingDiv.appendChild(document.createElement("span"));',
+'					this.expander.className = "expander unselectable greyedout";',
+'					this.expander.unselectable = true;',
+'					var expanderText = this.group.expanded ? "-" : "+";',
+'					this.expanderTextNode = this.expander.appendChild(document.createTextNode(expanderText));',
+'					',
+'					this.headingDiv.appendChild(document.createTextNode(" " + this.group.name));',
+'',
+'					this.contentDiv = this.mainDiv.appendChild(document.createElement("div"));',
+'					var contentCssClass = this.group.expanded ? "expanded" : "collapsed";',
+'					this.contentDiv.className = "groupcontent " + contentCssClass;',
+'',
+'					this.expander.onclick = function() {',
+'						if (groupElementContainer.group.expandable) {',
+'							groupElementContainer.group.toggleExpanded();',
+'						}',
+'					};',
+'				}',
+'			}',
+'',
+'			GroupElementContainer.prototype = new LogItemContainerElement();',
+'',
+'			copyProperties(GroupElementContainer.prototype, {',
+'				toggleExpanded: function() {',
+'					if (!this.isRoot) {',
+'						var oldCssClass, newCssClass, expanderText;',
+'						if (this.group.expanded) {',
+'							newCssClass = "expanded";',
+'							oldCssClass = "collapsed";',
+'							expanderText = "-";',
+'						} else {',
+'							newCssClass = "collapsed";',
+'							oldCssClass = "expanded";',
+'							expanderText = "+";',
+'						}',
+'						replaceClass(this.contentDiv, newCssClass, oldCssClass);',
+'						this.expanderTextNode.nodeValue = expanderText;',
+'					}',
+'				},',
+'',
+'				remove: function() {',
+'					if (!this.isRoot) {',
+'						this.headingDiv = null;',
+'						this.expander.onclick = null;',
+'						this.expander = null;',
+'						this.expanderTextNode = null;',
+'						this.contentDiv = null;',
+'						this.containerDomNode = null;',
+'						this.mainDiv.parentNode.removeChild(this.mainDiv);',
+'						this.mainDiv = null;',
+'					}',
+'				},',
+'',
+'				reverseChildren: function() {',
+'					// Invert the order of the log entries',
+'					var node = null;',
+'',
+'					// Remove all the log container nodes',
+'					var childDomNodes = [];',
+'					while ((node = this.contentDiv.firstChild)) {',
+'						this.contentDiv.removeChild(node);',
+'						childDomNodes.push(node);',
+'					}',
+'',
+'					// Put them all back in reverse order',
+'					while ((node = childDomNodes.pop())) {',
+'						this.contentDiv.appendChild(node);',
+'					}',
+'				},',
+'',
+'				update: function() {',
+'					if (!this.isRoot) {',
+'						if (this.group.expandable) {',
+'							removeClass(this.expander, "greyedout");',
+'						} else {',
+'							addClass(this.expander, "greyedout");',
+'						}',
+'					}',
+'				},',
+'',
+'				clear: function() {',
+'					if (this.isRoot) {',
+'						this.contentDiv.innerHTML = "";',
+'					}',
+'				}',
+'			});',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function Group(name, isRoot, initiallyExpanded) {',
+'				this.name = name;',
+'				this.group = null;',
+'				this.isRoot = isRoot;',
+'				this.initiallyExpanded = initiallyExpanded;',
+'				this.elementContainers = [];',
+'				this.children = [];',
+'				this.expanded = initiallyExpanded;',
+'				this.rendered = false;',
+'				this.expandable = false;',
+'			}',
+'',
+'			Group.prototype = new LogItem();',
+'',
+'			copyProperties(Group.prototype, {',
+'				addChild: function(logItem) {',
+'					this.children.push(logItem);',
+'					logItem.group = this;',
+'				},',
+'',
+'				render: function() {',
+'					if (isIe) {',
+'						var unwrappedDomContainer, wrappedDomContainer;',
+'						if (this.isRoot) {',
+'							unwrappedDomContainer = logMainContainer;',
+'							wrappedDomContainer = logMainContainer;',
+'						} else {',
+'							unwrappedDomContainer = this.getUnwrappedDomContainer();',
+'							wrappedDomContainer = this.getWrappedDomContainer();',
+'						}',
+'						this.unwrappedElementContainer = new GroupElementContainer(this, unwrappedDomContainer, this.isRoot, false);',
+'						this.wrappedElementContainer = new GroupElementContainer(this, wrappedDomContainer, this.isRoot, true);',
+'						this.elementContainers = [this.unwrappedElementContainer, this.wrappedElementContainer];',
+'					} else {',
+'						var mainDomContainer = this.isRoot ? logMainContainer : this.getMainDomContainer();',
+'						this.mainElementContainer = new GroupElementContainer(this, mainDomContainer, this.isRoot, false);',
+'						this.elementContainers = [this.mainElementContainer];',
+'					}',
+'					this.rendered = true;',
+'				},',
+'',
+'				toggleExpanded: function() {',
+'					this.expanded = !this.expanded;',
+'					for (var i = 0, len = this.elementContainers.length; i < len; i++) {',
+'						this.elementContainers[i].toggleExpanded();',
+'					}',
+'				},',
+'',
+'				expand: function() {',
+'					if (!this.expanded) {',
+'						this.toggleExpanded();',
+'					}',
+'				},',
+'',
+'				accept: function(visitor) {',
+'					visitor.visitGroup(this);',
+'				},',
+'',
+'				reverseChildren: function() {',
+'					if (this.rendered) {',
+'						for (var i = 0, len = this.elementContainers.length; i < len; i++) {',
+'							this.elementContainers[i].reverseChildren();',
+'						}',
+'					}',
+'				},',
+'',
+'				update: function() {',
+'					var previouslyExpandable = this.expandable;',
+'					this.expandable = (this.children.length !== 0);',
+'					if (this.expandable !== previouslyExpandable) {',
+'						for (var i = 0, len = this.elementContainers.length; i < len; i++) {',
+'							this.elementContainers[i].update();',
+'						}',
+'					}',
+'				},',
+'',
+'				flatten: function() {',
+'					var visitor = new GroupFlattener();',
+'					this.accept(visitor);',
+'					return visitor.logEntriesAndSeparators;',
+'				},',
+'',
+'				removeChild: function(child, doUpdate) {',
+'					array_remove(this.children, child);',
+'					child.group = null;',
+'					if (doUpdate) {',
+'						this.update();',
+'					}',
+'				},',
+'',
+'				remove: function(doUpdate, removeFromGroup) {',
+'					for (var i = 0, len = this.children.length; i < len; i++) {',
+'						this.children[i].remove(false, false);',
+'					}',
+'					this.children = [];',
+'					this.update();',
+'					if (this === currentGroup) {',
+'						currentGroup = this.group;',
+'					}',
+'					this.doRemove(doUpdate, removeFromGroup);',
+'				},',
+'',
+'				serialize: function(items) {',
+'					items.push([LogItem.serializedItemKeys.GROUP_START, this.name]);',
+'					for (var i = 0, len = this.children.length; i < len; i++) {',
+'						this.children[i].serialize(items);',
+'					}',
+'					if (this !== currentGroup) {',
+'						items.push([LogItem.serializedItemKeys.GROUP_END]);',
+'					}',
+'				},',
+'',
+'				clear: function() {',
+'					for (var i = 0, len = this.elementContainers.length; i < len; i++) {',
+'						this.elementContainers[i].clear();',
+'					}',
+'				}',
+'			});',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function LogEntryElementContainer() {',
+'			}',
+'',
+'			LogEntryElementContainer.prototype = new LogItemContainerElement();',
+'',
+'			copyProperties(LogEntryElementContainer.prototype, {',
+'				remove: function() {',
+'					this.doRemove();',
+'				},',
+'',
+'				doRemove: function() {',
+'					this.mainDiv.parentNode.removeChild(this.mainDiv);',
+'					this.mainDiv = null;',
+'					this.contentElement = null;',
+'					this.containerDomNode = null;',
+'				},',
+'',
+'				setContent: function(content, wrappedContent) {',
+'					if (content === this.formattedMessage) {',
+'						this.contentElement.innerHTML = "";',
+'						this.contentElement.appendChild(document.createTextNode(this.formattedMessage));',
+'					} else {',
+'						this.contentElement.innerHTML = content;',
+'					}',
+'				},',
+'',
+'				setSearchMatch: function(isMatch) {',
+'					var oldCssClass = isMatch ? "searchnonmatch" : "searchmatch";',
+'					var newCssClass = isMatch ? "searchmatch" : "searchnonmatch";',
+'					replaceClass(this.mainDiv, newCssClass, oldCssClass);',
+'				},',
+'',
+'				clearSearch: function() {',
+'					removeClass(this.mainDiv, "searchmatch");',
+'					removeClass(this.mainDiv, "searchnonmatch");',
+'				}',
+'			});',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function LogEntryWrappedElementContainer(logEntry, containerDomNode) {',
+'				this.logEntry = logEntry;',
+'				this.containerDomNode = containerDomNode;',
+'				this.mainDiv = document.createElement("div");',
+'				this.mainDiv.appendChild(document.createTextNode(this.logEntry.formattedMessage));',
+'				this.mainDiv.className = "logentry wrapped " + this.logEntry.level;',
+'				this.contentElement = this.mainDiv;',
+'			}',
+'',
+'			LogEntryWrappedElementContainer.prototype = new LogEntryElementContainer();',
+'',
+'			LogEntryWrappedElementContainer.prototype.setContent = function(content, wrappedContent) {',
+'				if (content === this.formattedMessage) {',
+'					this.contentElement.innerHTML = "";',
+'					this.contentElement.appendChild(document.createTextNode(this.formattedMessage));',
+'				} else {',
+'					this.contentElement.innerHTML = wrappedContent;',
+'				}',
+'			};',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function LogEntryUnwrappedElementContainer(logEntry, containerDomNode) {',
+'				this.logEntry = logEntry;',
+'				this.containerDomNode = containerDomNode;',
+'				this.mainDiv = document.createElement("div");',
+'				this.mainDiv.className = "logentry unwrapped " + this.logEntry.level;',
+'				this.pre = this.mainDiv.appendChild(document.createElement("pre"));',
+'				this.pre.appendChild(document.createTextNode(this.logEntry.formattedMessage));',
+'				this.pre.className = "unwrapped";',
+'				this.contentElement = this.pre;',
+'			}',
+'',
+'			LogEntryUnwrappedElementContainer.prototype = new LogEntryElementContainer();',
+'',
+'			LogEntryUnwrappedElementContainer.prototype.remove = function() {',
+'				this.doRemove();',
+'				this.pre = null;',
+'			};',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function LogEntryMainElementContainer(logEntry, containerDomNode) {',
+'				this.logEntry = logEntry;',
+'				this.containerDomNode = containerDomNode;',
+'				this.mainDiv = document.createElement("div");',
+'				this.mainDiv.className = "logentry nonielogentry " + this.logEntry.level;',
+'				this.contentElement = this.mainDiv.appendChild(document.createElement("span"));',
+'				this.contentElement.appendChild(document.createTextNode(this.logEntry.formattedMessage));',
+'			}',
+'',
+'			LogEntryMainElementContainer.prototype = new LogEntryElementContainer();',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function LogEntry(level, formattedMessage) {',
+'				this.level = level;',
+'				this.formattedMessage = formattedMessage;',
+'				this.rendered = false;',
+'			}',
+'',
+'			LogEntry.prototype = new LogItem();',
+'',
+'			copyProperties(LogEntry.prototype, {',
+'				render: function() {',
+'					var logEntry = this;',
+'					var containerDomNode = this.group.contentDiv;',
+'',
+'					// Support for the CSS attribute white-space in IE for Windows is',
+'					// non-existent pre version 6 and slightly odd in 6, so instead',
+'					// use two different HTML elements',
+'					if (isIe) {',
+'						this.formattedMessage = this.formattedMessage.replace(/\\r\\n/g, "\\r"); // Workaround for IE\'s treatment of white space',
+'						this.unwrappedElementContainer = new LogEntryUnwrappedElementContainer(this, this.getUnwrappedDomContainer());',
+'						this.wrappedElementContainer = new LogEntryWrappedElementContainer(this, this.getWrappedDomContainer());',
+'						this.elementContainers = [this.unwrappedElementContainer, this.wrappedElementContainer];',
+'					} else {',
+'						this.mainElementContainer = new LogEntryMainElementContainer(this, this.getMainDomContainer());',
+'						this.elementContainers = [this.mainElementContainer];',
+'					}',
+'					this.content = this.formattedMessage;',
+'					this.rendered = true;',
+'				},',
+'',
+'				setContent: function(content, wrappedContent) {',
+'					if (content != this.content) {',
+'						if (isIe && (content !== this.formattedMessage)) {',
+'							content = content.replace(/\\r\\n/g, "\\r"); // Workaround for IE\'s treatment of white space',
+'						}',
+'						for (var i = 0, len = this.elementContainers.length; i < len; i++) {',
+'							this.elementContainers[i].setContent(content, wrappedContent);',
+'						}',
+'						this.content = content;',
+'					}',
+'				},',
+'',
+'				getSearchMatches: function() {',
+'					var matches = [];',
+'					var i, len;',
+'					if (isIe) {',
+'						var unwrappedEls = getElementsByClass(this.unwrappedElementContainer.mainDiv, "searchterm", "span");',
+'						var wrappedEls = getElementsByClass(this.wrappedElementContainer.mainDiv, "searchterm", "span");',
+'						for (i = 0, len = unwrappedEls.length; i < len; i++) {',
+'							matches[i] = new Match(this.level, null, unwrappedEls[i], wrappedEls[i]);',
+'						}',
+'					} else {',
+'						var els = getElementsByClass(this.mainElementContainer.mainDiv, "searchterm", "span");',
+'						for (i = 0, len = els.length; i < len; i++) {',
+'							matches[i] = new Match(this.level, els[i]);',
+'						}',
+'					}',
+'					return matches;',
+'				},',
+'',
+'				setSearchMatch: function(isMatch) {',
+'					for (var i = 0, len = this.elementContainers.length; i < len; i++) {',
+'						this.elementContainers[i].setSearchMatch(isMatch);',
+'					}',
+'				},',
+'',
+'				clearSearch: function() {',
+'					for (var i = 0, len = this.elementContainers.length; i < len; i++) {',
+'						this.elementContainers[i].clearSearch();',
+'					}',
+'				},',
+'',
+'				accept: function(visitor) {',
+'					visitor.visitLogEntry(this);',
+'				},',
+'',
+'				serialize: function(items) {',
+'					items.push([LogItem.serializedItemKeys.LOG_ENTRY, this.level, this.formattedMessage]);',
+'				}',
+'			});',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function LogItemVisitor() {',
+'			}',
+'',
+'			LogItemVisitor.prototype = {',
+'				visit: function(logItem) {',
+'				},',
+'',
+'				visitParent: function(logItem) {',
+'					if (logItem.group) {',
+'						logItem.group.accept(this);',
+'					}',
+'				},',
+'',
+'				visitChildren: function(logItem) {',
+'					for (var i = 0, len = logItem.children.length; i < len; i++) {',
+'						logItem.children[i].accept(this);',
+'					}',
+'				},',
+'',
+'				visitLogEntry: function(logEntry) {',
+'					this.visit(logEntry);',
+'				},',
+'',
+'				visitSeparator: function(separator) {',
+'					this.visit(separator);',
+'				},',
+'',
+'				visitGroup: function(group) {',
+'					this.visit(group);',
+'				}',
+'			};',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function GroupFlattener() {',
+'				this.logEntriesAndSeparators = [];',
+'			}',
+'',
+'			GroupFlattener.prototype = new LogItemVisitor();',
+'',
+'			GroupFlattener.prototype.visitGroup = function(group) {',
+'				this.visitChildren(group);',
+'			};',
+'',
+'			GroupFlattener.prototype.visitLogEntry = function(logEntry) {',
+'				this.logEntriesAndSeparators.push(logEntry);',
+'			};',
+'',
+'			GroupFlattener.prototype.visitSeparator = function(separator) {',
+'				this.logEntriesAndSeparators.push(separator);',
+'			};',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			window.onload = function() {',
+'				// Sort out document.domain',
+'				if (location.search) {',
+'					var queryBits = unescape(location.search).substr(1).split("&"), nameValueBits;',
+'					for (var i = 0, len = queryBits.length; i < len; i++) {',
+'						nameValueBits = queryBits[i].split("=");',
+'						if (nameValueBits[0] == "log4javascript_domain") {',
+'							document.domain = nameValueBits[1];',
+'							break;',
+'						}',
+'					}',
+'				}',
+'',
+'				// Create DOM objects',
+'				logMainContainer = $("log");',
+'				if (isIePre7) {',
+'					addClass(logMainContainer, "oldIe");',
+'				}',
+'',
+'				rootGroup = new Group("root", true);',
+'				rootGroup.render();',
+'				currentGroup = rootGroup;',
+'				',
+'				setCommandInputWidth();',
+'				setLogContainerHeight();',
+'				toggleLoggingEnabled();',
+'				toggleSearchEnabled();',
+'				toggleSearchFilter();',
+'				toggleSearchHighlight();',
+'				applyFilters();',
+'				checkAllLevels();',
+'				toggleWrap();',
+'				toggleNewestAtTop();',
+'				toggleScrollToLatest();',
+'				renderQueuedLogItems();',
+'				loaded = true;',
+'				$("command").value = "";',
+'				$("command").autocomplete = "off";',
+'				$("command").onkeydown = function(evt) {',
+'					evt = getEvent(evt);',
+'					if (evt.keyCode == 10 || evt.keyCode == 13) { // Return/Enter',
+'						evalCommandLine();',
+'						stopPropagation(evt);',
+'					} else if (evt.keyCode == 27) { // Escape',
+'						this.value = "";',
+'						this.focus();',
+'					} else if (evt.keyCode == 38 && commandHistory.length > 0) { // Up',
+'						currentCommandIndex = Math.max(0, currentCommandIndex - 1);',
+'						this.value = commandHistory[currentCommandIndex];',
+'						moveCaretToEnd(this);',
+'					} else if (evt.keyCode == 40 && commandHistory.length > 0) { // Down',
+'						currentCommandIndex = Math.min(commandHistory.length - 1, currentCommandIndex + 1);',
+'						this.value = commandHistory[currentCommandIndex];',
+'						moveCaretToEnd(this);',
+'					}',
+'				};',
+'',
+'				// Prevent the keypress moving the caret in Firefox',
+'				$("command").onkeypress = function(evt) {',
+'					evt = getEvent(evt);',
+'					if (evt.keyCode == 38 && commandHistory.length > 0 && evt.preventDefault) { // Up',
+'						evt.preventDefault();',
+'					}',
+'				};',
+'',
+'				// Prevent the keyup event blurring the input in Opera',
+'				$("command").onkeyup = function(evt) {',
+'					evt = getEvent(evt);',
+'					if (evt.keyCode == 27 && evt.preventDefault) { // Up',
+'						evt.preventDefault();',
+'						this.focus();',
+'					}',
+'				};',
+'',
+'				// Add document keyboard shortcuts',
+'				document.onkeydown = function keyEventHandler(evt) {',
+'					evt = getEvent(evt);',
+'					switch (evt.keyCode) {',
+'						case 69: // Ctrl + shift + E: re-execute last command',
+'							if (evt.shiftKey && (evt.ctrlKey || evt.metaKey)) {',
+'								evalLastCommand();',
+'								cancelKeyEvent(evt);',
+'								return false;',
+'							}',
+'							break;',
+'						case 75: // Ctrl + shift + K: focus search',
+'							if (evt.shiftKey && (evt.ctrlKey || evt.metaKey)) {',
+'								focusSearch();',
+'								cancelKeyEvent(evt);',
+'								return false;',
+'							}',
+'							break;',
+'						case 40: // Ctrl + shift + down arrow: focus command line',
+'						case 76: // Ctrl + shift + L: focus command line',
+'							if (evt.shiftKey && (evt.ctrlKey || evt.metaKey)) {',
+'								focusCommandLine();',
+'								cancelKeyEvent(evt);',
+'								return false;',
+'							}',
+'							break;',
+'					}',
+'				};',
+'',
+'				// Workaround to make sure log div starts at the correct size',
+'				setTimeout(setLogContainerHeight, 20);',
+'',
+'				setShowCommandLine(showCommandLine);',
+'				doSearch();',
+'			};',
+'',
+'			window.onunload = function() {',
+'				if (mainWindowExists()) {',
+'					appender.unload();',
+'				}',
+'				appender = null;',
+'			};',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function toggleLoggingEnabled() {',
+'				setLoggingEnabled($("enableLogging").checked);',
+'			}',
+'',
+'			function setLoggingEnabled(enable) {',
+'				loggingEnabled = enable;',
+'			}',
+'',
+'			var appender = null;',
+'',
+'			function setAppender(appenderParam) {',
+'				appender = appenderParam;',
+'			}',
+'',
+'			function setShowCloseButton(showCloseButton) {',
+'				$("closeButton").style.display = showCloseButton ? "inline" : "none";',
+'			}',
+'',
+'			function setShowHideButton(showHideButton) {',
+'				$("hideButton").style.display = showHideButton ? "inline" : "none";',
+'			}',
+'',
+'			var newestAtTop = false;',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function LogItemContentReverser() {',
+'			}',
+'			',
+'			LogItemContentReverser.prototype = new LogItemVisitor();',
+'			',
+'			LogItemContentReverser.prototype.visitGroup = function(group) {',
+'				group.reverseChildren();',
+'				this.visitChildren(group);',
+'			};',
+'',
+'			/*----------------------------------------------------------------*/',
+'',
+'			function setNewestAtTop(isNewestAtTop) {',
+'				var oldNewestAtTop = newestAtTop;',
+'				var i, iLen, j, jLen;',
+'				newestAtTop = Boolean(isNewestAtTop);',
+'				if (oldNewestAtTop != newestAtTop) {',
+'					var visitor = new LogItemContentReverser();',
+'					rootGroup.accept(visitor);',
+'',
+'					// Reassemble the matches array',
+'					if (currentSearch) {',
+'						var currentMatch = currentSearch.matches[currentMatchIndex];',
+'						var matchIndex = 0;',
+'						var matches = [];',
+'						var actOnLogEntry = function(logEntry) {',
+'							var logEntryMatches = logEntry.getSearchMatches();',
+'							for (j = 0, jLen = logEntryMatches.length; j < jLen; j++) {',
+'								matches[matchIndex] = logEntryMatches[j];',
+'								if (currentMatch && logEntryMatches[j].equals(currentMatch)) {',
+'									currentMatchIndex = matchIndex;',
+'								}',
+'								matchIndex++;',
+'							}',
+'						};',
+'						if (newestAtTop) {',
+'							for (i = logEntries.length - 1; i >= 0; i--) {',
+'								actOnLogEntry(logEntries[i]);',
+'							}',
+'						} else {',
+'							for (i = 0, iLen = logEntries.length; i < iLen; i++) {',
+'								actOnLogEntry(logEntries[i]);',
+'							}',
+'						}',
+'						currentSearch.matches = matches;',
+'						if (currentMatch) {',
+'							currentMatch.setCurrent();',
+'						}',
+'					} else if (scrollToLatest) {',
+'						doScrollToLatest();',
+'					}',
+'				}',
+'				$("newestAtTop").checked = isNewestAtTop;',
+'			}',
+'',
+'			function toggleNewestAtTop() {',
+'				var isNewestAtTop = $("newestAtTop").checked;',
+'				setNewestAtTop(isNewestAtTop);',
+'			}',
+'',
+'			var scrollToLatest = true;',
+'',
+'			function setScrollToLatest(isScrollToLatest) {',
+'				scrollToLatest = isScrollToLatest;',
+'				if (scrollToLatest) {',
+'					doScrollToLatest();',
+'				}',
+'				$("scrollToLatest").checked = isScrollToLatest;',
+'			}',
+'',
+'			function toggleScrollToLatest() {',
+'				var isScrollToLatest = $("scrollToLatest").checked;',
+'				setScrollToLatest(isScrollToLatest);',
+'			}',
+'',
+'			function doScrollToLatest() {',
+'				var l = logMainContainer;',
+'				if (typeof l.scrollTop != "undefined") {',
+'					if (newestAtTop) {',
+'						l.scrollTop = 0;',
+'					} else {',
+'						var latestLogEntry = l.lastChild;',
+'						if (latestLogEntry) {',
+'							l.scrollTop = l.scrollHeight;',
+'						}',
+'					}',
+'				}',
+'			}',
+'',
+'			var closeIfOpenerCloses = true;',
+'',
+'			function setCloseIfOpenerCloses(isCloseIfOpenerCloses) {',
+'				closeIfOpenerCloses = isCloseIfOpenerCloses;',
+'			}',
+'',
+'			var maxMessages = null;',
+'',
+'			function setMaxMessages(max) {',
+'				maxMessages = max;',
+'				pruneLogEntries();',
+'			}',
+'',
+'			var showCommandLine = false;',
+'',
+'			function setShowCommandLine(isShowCommandLine) {',
+'				showCommandLine = isShowCommandLine;',
+'				if (loaded) {',
+'					$("commandLine").style.display = showCommandLine ? "block" : "none";',
+'					setCommandInputWidth();',
+'					setLogContainerHeight();',
+'				}',
+'			}',
+'',
+'			function focusCommandLine() {',
+'				if (loaded) {',
+'					$("command").focus();',
+'				}',
+'			}',
+'',
+'			function focusSearch() {',
+'				if (loaded) {',
+'					$("searchBox").focus();',
+'				}',
+'			}',
+'',
+'			function getLogItems() {',
+'				var items = [];',
+'				for (var i = 0, len = logItems.length; i < len; i++) {',
+'					logItems[i].serialize(items);',
+'				}',
+'				return items;',
+'			}',
+'',
+'			function setLogItems(items) {',
+'				var loggingReallyEnabled = loggingEnabled;',
+'				// Temporarily turn logging on',
+'				loggingEnabled = true;',
+'				for (var i = 0, len = items.length; i < len; i++) {',
+'					switch (items[i][0]) {',
+'						case LogItem.serializedItemKeys.LOG_ENTRY:',
+'							log(items[i][1], items[i][2]);',
+'							break;',
+'						case LogItem.serializedItemKeys.GROUP_START:',
+'							group(items[i][1]);',
+'							break;',
+'						case LogItem.serializedItemKeys.GROUP_END:',
+'							groupEnd();',
+'							break;',
+'					}',
+'				}',
+'				loggingEnabled = loggingReallyEnabled;',
+'			}',
+'',
+'			function log(logLevel, formattedMessage) {',
+'				if (loggingEnabled) {',
+'					var logEntry = new LogEntry(logLevel, formattedMessage);',
+'					logEntries.push(logEntry);',
+'					logEntriesAndSeparators.push(logEntry);',
+'					logItems.push(logEntry);',
+'					currentGroup.addChild(logEntry);',
+'					if (loaded) {',
+'						if (logQueuedEventsTimer !== null) {',
+'							clearTimeout(logQueuedEventsTimer);',
+'						}',
+'						logQueuedEventsTimer = setTimeout(renderQueuedLogItems, renderDelay);',
+'						unrenderedLogItemsExist = true;',
+'					}',
+'				}',
+'			}',
+'',
+'			function renderQueuedLogItems() {',
+'				logQueuedEventsTimer = null;',
+'				var pruned = pruneLogEntries();',
+'',
+'				// Render any unrendered log entries and apply the current search to them',
+'				var initiallyHasMatches = currentSearch ? currentSearch.hasMatches() : false;',
+'				for (var i = 0, len = logItems.length; i < len; i++) {',
+'					if (!logItems[i].rendered) {',
+'						logItems[i].render();',
+'						logItems[i].appendToLog();',
+'						if (currentSearch && (logItems[i] instanceof LogEntry)) {',
+'							currentSearch.applyTo(logItems[i]);',
+'						}',
+'					}',
+'				}',
+'				if (currentSearch) {',
+'					if (pruned) {',
+'						if (currentSearch.hasVisibleMatches()) {',
+'							if (currentMatchIndex === null) {',
+'								setCurrentMatchIndex(0);',
+'							}',
+'							displayMatches();',
+'						} else {',
+'							displayNoMatches();',
+'						}',
+'					} else if (!initiallyHasMatches && currentSearch.hasVisibleMatches()) {',
+'						setCurrentMatchIndex(0);',
+'						displayMatches();',
+'					}',
+'				}',
+'				if (scrollToLatest) {',
+'					doScrollToLatest();',
+'				}',
+'				unrenderedLogItemsExist = false;',
+'			}',
+'',
+'			function pruneLogEntries() {',
+'				if ((maxMessages !== null) && (logEntriesAndSeparators.length > maxMessages)) {',
+'					var numberToDelete = logEntriesAndSeparators.length - maxMessages;',
+'					var prunedLogEntries = logEntriesAndSeparators.slice(0, numberToDelete);',
+'					if (currentSearch) {',
+'						currentSearch.removeMatches(prunedLogEntries);',
+'					}',
+'					var group;',
+'					for (var i = 0; i < numberToDelete; i++) {',
+'						group = logEntriesAndSeparators[i].group;',
+'						array_remove(logItems, logEntriesAndSeparators[i]);',
+'						array_remove(logEntries, logEntriesAndSeparators[i]);',
+'						logEntriesAndSeparators[i].remove(true, true);',
+'						if (group.children.length === 0 && group !== currentGroup && group !== rootGroup) {',
+'							array_remove(logItems, group);',
+'							group.remove(true, true);',
+'						}',
+'					}',
+'					logEntriesAndSeparators = array_removeFromStart(logEntriesAndSeparators, numberToDelete);',
+'					return true;',
+'				}',
+'				return false;',
+'			}',
+'',
+'			function group(name, startExpanded) {',
+'				if (loggingEnabled) {',
+'					initiallyExpanded = (typeof startExpanded === "undefined") ? true : Boolean(startExpanded);',
+'					var newGroup = new Group(name, false, initiallyExpanded);',
+'					currentGroup.addChild(newGroup);',
+'					currentGroup = newGroup;',
+'					logItems.push(newGroup);',
+'					if (loaded) {',
+'						if (logQueuedEventsTimer !== null) {',
+'							clearTimeout(logQueuedEventsTimer);',
+'						}',
+'						logQueuedEventsTimer = setTimeout(renderQueuedLogItems, renderDelay);',
+'						unrenderedLogItemsExist = true;',
+'					}',
+'				}',
+'			}',
+'',
+'			function groupEnd() {',
+'				currentGroup = (currentGroup === rootGroup) ? rootGroup : currentGroup.group;',
+'			}',
+'',
+'			function mainPageReloaded() {',
+'				currentGroup = rootGroup;',
+'				var separator = new Separator();',
+'				logEntriesAndSeparators.push(separator);',
+'				logItems.push(separator);',
+'				currentGroup.addChild(separator);',
+'			}',
+'',
+'			function closeWindow() {',
+'				if (appender && mainWindowExists()) {',
+'					appender.close(true);',
+'				} else {',
+'					window.close();',
+'				}',
+'			}',
+'',
+'			function hide() {',
+'				if (appender && mainWindowExists()) {',
+'					appender.hide();',
+'				}',
+'			}',
+'',
+'			var mainWindow = window;',
+'			var windowId = "log4javascriptConsoleWindow_" + new Date().getTime() + "_" + ("" + Math.random()).substr(2);',
+'',
+'			function setMainWindow(win) {',
+'				mainWindow = win;',
+'				mainWindow[windowId] = window;',
+'				// If this is a pop-up, poll the opener to see if it\'s closed',
+'				if (opener && closeIfOpenerCloses) {',
+'					pollOpener();',
+'				}',
+'			}',
+'',
+'			function pollOpener() {',
+'				if (closeIfOpenerCloses) {',
+'					if (mainWindowExists()) {',
+'						setTimeout(pollOpener, 500);',
+'					} else {',
+'						closeWindow();',
+'					}',
+'				}',
+'			}',
+'',
+'			function mainWindowExists() {',
+'				try {',
+'					return (mainWindow && !mainWindow.closed &&',
+'						mainWindow[windowId] == window);',
+'				} catch (ex) {}',
+'				return false;',
+'			}',
+'',
+'			var logLevels = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"];',
+'',
+'			function getCheckBox(logLevel) {',
+'				return $("switch_" + logLevel);',
+'			}',
+'',
+'			function getIeWrappedLogContainer() {',
+'				return $("log_wrapped");',
+'			}',
+'',
+'			function getIeUnwrappedLogContainer() {',
+'				return $("log_unwrapped");',
+'			}',
+'',
+'			function applyFilters() {',
+'				for (var i = 0; i < logLevels.length; i++) {',
+'					if (getCheckBox(logLevels[i]).checked) {',
+'						addClass(logMainContainer, logLevels[i]);',
+'					} else {',
+'						removeClass(logMainContainer, logLevels[i]);',
+'					}',
+'				}',
+'				updateSearchFromFilters();',
+'			}',
+'',
+'			function toggleAllLevels() {',
+'				var turnOn = $("switch_ALL").checked;',
+'				for (var i = 0; i < logLevels.length; i++) {',
+'					getCheckBox(logLevels[i]).checked = turnOn;',
+'					if (turnOn) {',
+'						addClass(logMainContainer, logLevels[i]);',
+'					} else {',
+'						removeClass(logMainContainer, logLevels[i]);',
+'					}',
+'				}',
+'			}',
+'',
+'			function checkAllLevels() {',
+'				for (var i = 0; i < logLevels.length; i++) {',
+'					if (!getCheckBox(logLevels[i]).checked) {',
+'						getCheckBox("ALL").checked = false;',
+'						return;',
+'					}',
+'				}',
+'				getCheckBox("ALL").checked = true;',
+'			}',
+'',
+'			function clearLog() {',
+'				rootGroup.clear();',
+'				currentGroup = rootGroup;',
+'				logEntries = [];',
+'				logItems = [];',
+'				logEntriesAndSeparators = [];',
+' 				doSearch();',
+'			}',
+'',
+'			function toggleWrap() {',
+'				var enable = $("wrap").checked;',
+'				if (enable) {',
+'					addClass(logMainContainer, "wrap");',
+'				} else {',
+'					removeClass(logMainContainer, "wrap");',
+'				}',
+'				refreshCurrentMatch();',
+'			}',
+'',
+'			/* ------------------------------------------------------------------- */',
+'',
+'			// Search',
+'',
+'			var searchTimer = null;',
+'',
+'			function scheduleSearch() {',
+'				try {',
+'					clearTimeout(searchTimer);',
+'				} catch (ex) {',
+'					// Do nothing',
+'				}',
+'				searchTimer = setTimeout(doSearch, 500);',
+'			}',
+'',
+'			function Search(searchTerm, isRegex, searchRegex, isCaseSensitive) {',
+'				this.searchTerm = searchTerm;',
+'				this.isRegex = isRegex;',
+'				this.searchRegex = searchRegex;',
+'				this.isCaseSensitive = isCaseSensitive;',
+'				this.matches = [];',
+'			}',
+'',
+'			Search.prototype = {',
+'				hasMatches: function() {',
+'					return this.matches.length > 0;',
+'				},',
+'',
+'				hasVisibleMatches: function() {',
+'					if (this.hasMatches()) {',
+'						for (var i = 0; i < this.matches.length; i++) {',
+'							if (this.matches[i].isVisible()) {',
+'								return true;',
+'							}',
+'						}',
+'					}',
+'					return false;',
+'				},',
+'',
+'				match: function(logEntry) {',
+'					var entryText = String(logEntry.formattedMessage);',
+'					var matchesSearch = false;',
+'					if (this.isRegex) {',
+'						matchesSearch = this.searchRegex.test(entryText);',
+'					} else if (this.isCaseSensitive) {',
+'						matchesSearch = (entryText.indexOf(this.searchTerm) > -1);',
+'					} else {',
+'						matchesSearch = (entryText.toLowerCase().indexOf(this.searchTerm.toLowerCase()) > -1);',
+'					}',
+'					return matchesSearch;',
+'				},',
+'',
+'				getNextVisibleMatchIndex: function() {',
+'					for (var i = currentMatchIndex + 1; i < this.matches.length; i++) {',
+'						if (this.matches[i].isVisible()) {',
+'							return i;',
+'						}',
+'					}',
+'					// Start again from the first match',
+'					for (i = 0; i <= currentMatchIndex; i++) {',
+'						if (this.matches[i].isVisible()) {',
+'							return i;',
+'						}',
+'					}',
+'					return -1;',
+'				},',
+'',
+'				getPreviousVisibleMatchIndex: function() {',
+'					for (var i = currentMatchIndex - 1; i >= 0; i--) {',
+'						if (this.matches[i].isVisible()) {',
+'							return i;',
+'						}',
+'					}',
+'					// Start again from the last match',
+'					for (var i = this.matches.length - 1; i >= currentMatchIndex; i--) {',
+'						if (this.matches[i].isVisible()) {',
+'							return i;',
+'						}',
+'					}',
+'					return -1;',
+'				},',
+'',
+'				applyTo: function(logEntry) {',
+'					var doesMatch = this.match(logEntry);',
+'					if (doesMatch) {',
+'						logEntry.group.expand();',
+'						logEntry.setSearchMatch(true);',
+'						var logEntryContent;',
+'						var wrappedLogEntryContent;',
+'						var searchTermReplacementStartTag = "<span class=\\\"searchterm\\\">";',
+'						var searchTermReplacementEndTag = "<" + "/span>";',
+'						var preTagName = isIe ? "pre" : "span";',
+'						var preStartTag = "<" + preTagName + " class=\\\"pre\\\">";',
+'						var preEndTag = "<" + "/" + preTagName + ">";',
+'						var startIndex = 0;',
+'						var searchIndex, matchedText, textBeforeMatch;',
+'						if (this.isRegex) {',
+'							var flags = this.isCaseSensitive ? "g" : "gi";',
+'							var capturingRegex = new RegExp("(" + this.searchRegex.source + ")", flags);',
+'',
+'							// Replace the search term with temporary tokens for the start and end tags',
+'							var rnd = ("" + Math.random()).substr(2);',
+'							var startToken = "%%s" + rnd + "%%";',
+'							var endToken = "%%e" + rnd + "%%";',
+'							logEntryContent = logEntry.formattedMessage.replace(capturingRegex, startToken + "$1" + endToken);',
+'',
+'							// Escape the HTML to get rid of angle brackets',
+'							logEntryContent = escapeHtml(logEntryContent);',
+'',
+'							// Substitute the proper HTML back in for the search match',
+'							var result;',
+'							var searchString = logEntryContent;',
+'							logEntryContent = "";',
+'							wrappedLogEntryContent = "";',
+'							while ((searchIndex = searchString.indexOf(startToken, startIndex)) > -1) {',
+'								var endTokenIndex = searchString.indexOf(endToken, searchIndex);',
+'								matchedText = searchString.substring(searchIndex + startToken.length, endTokenIndex);',
+'								textBeforeMatch = searchString.substring(startIndex, searchIndex);',
+'								logEntryContent += preStartTag + textBeforeMatch + preEndTag;',
+'								logEntryContent += searchTermReplacementStartTag + preStartTag + matchedText +',
+'									preEndTag + searchTermReplacementEndTag;',
+'								if (isIe) {',
+'									wrappedLogEntryContent += textBeforeMatch + searchTermReplacementStartTag +',
+'										matchedText + searchTermReplacementEndTag;',
+'								}',
+'								startIndex = endTokenIndex + endToken.length;',
+'							}',
+'							logEntryContent += preStartTag + searchString.substr(startIndex) + preEndTag;',
+'							if (isIe) {',
+'								wrappedLogEntryContent += searchString.substr(startIndex);',
+'							}',
+'						} else {',
+'							logEntryContent = "";',
+'							wrappedLogEntryContent = "";',
+'							var searchTermReplacementLength = searchTermReplacementStartTag.length +',
+'								this.searchTerm.length + searchTermReplacementEndTag.length;',
+'							var searchTermLength = this.searchTerm.length;',
+'							var searchTermLowerCase = this.searchTerm.toLowerCase();',
+'							var logTextLowerCase = logEntry.formattedMessage.toLowerCase();',
+'							while ((searchIndex = logTextLowerCase.indexOf(searchTermLowerCase, startIndex)) > -1) {',
+'								matchedText = escapeHtml(logEntry.formattedMessage.substr(searchIndex, this.searchTerm.length));',
+'								textBeforeMatch = escapeHtml(logEntry.formattedMessage.substring(startIndex, searchIndex));',
+'								var searchTermReplacement = searchTermReplacementStartTag +',
+'									preStartTag + matchedText + preEndTag + searchTermReplacementEndTag;',
+'								logEntryContent += preStartTag + textBeforeMatch + preEndTag + searchTermReplacement;',
+'								if (isIe) {',
+'									wrappedLogEntryContent += textBeforeMatch + searchTermReplacementStartTag +',
+'										matchedText + searchTermReplacementEndTag;',
+'								}',
+'								startIndex = searchIndex + searchTermLength;',
+'							}',
+'							var textAfterLastMatch = escapeHtml(logEntry.formattedMessage.substr(startIndex));',
+'							logEntryContent += preStartTag + textAfterLastMatch + preEndTag;',
+'							if (isIe) {',
+'								wrappedLogEntryContent += textAfterLastMatch;',
+'							}',
+'						}',
+'						logEntry.setContent(logEntryContent, wrappedLogEntryContent);',
+'						var logEntryMatches = logEntry.getSearchMatches();',
+'						this.matches = this.matches.concat(logEntryMatches);',
+'					} else {',
+'						logEntry.setSearchMatch(false);',
+'						logEntry.setContent(logEntry.formattedMessage, logEntry.formattedMessage);',
+'					}',
+'					return doesMatch;',
+'				},',
+'',
+'				removeMatches: function(logEntries) {',
+'					var matchesToRemoveCount = 0;',
+'					var currentMatchRemoved = false;',
+'					var matchesToRemove = [];',
+'					var i, iLen, j, jLen;',
+'',
+'					// Establish the list of matches to be removed',
+'					for (i = 0, iLen = this.matches.length; i < iLen; i++) {',
+'						for (j = 0, jLen = logEntries.length; j < jLen; j++) {',
+'							if (this.matches[i].belongsTo(logEntries[j])) {',
+'								matchesToRemove.push(this.matches[i]);',
+'								if (i === currentMatchIndex) {',
+'									currentMatchRemoved = true;',
+'								}',
+'							}',
+'						}',
+'					}',
+'',
+'					// Set the new current match index if the current match has been deleted',
+'					// This will be the first match that appears after the first log entry being',
+'					// deleted, if one exists; otherwise, it\'s the first match overall',
+'					var newMatch = currentMatchRemoved ? null : this.matches[currentMatchIndex];',
+'					if (currentMatchRemoved) {',
+'						for (i = currentMatchIndex, iLen = this.matches.length; i < iLen; i++) {',
+'							if (this.matches[i].isVisible() && !array_contains(matchesToRemove, this.matches[i])) {',
+'								newMatch = this.matches[i];',
+'								break;',
+'							}',
+'						}',
+'					}',
+'',
+'					// Remove the matches',
+'					for (i = 0, iLen = matchesToRemove.length; i < iLen; i++) {',
+'						array_remove(this.matches, matchesToRemove[i]);',
+'						matchesToRemove[i].remove();',
+'					}',
+'',
+'					// Set the new match, if one exists',
+'					if (this.hasVisibleMatches()) {',
+'						if (newMatch === null) {',
+'							setCurrentMatchIndex(0);',
+'						} else {',
+'							// Get the index of the new match',
+'							var newMatchIndex = 0;',
+'							for (i = 0, iLen = this.matches.length; i < iLen; i++) {',
+'								if (newMatch === this.matches[i]) {',
+'									newMatchIndex = i;',
+'									break;',
+'								}',
+'							}',
+'							setCurrentMatchIndex(newMatchIndex);',
+'						}',
+'					} else {',
+'						currentMatchIndex = null;',
+'						displayNoMatches();',
+'					}',
+'				}',
+'			};',
+'',
+'			function getPageOffsetTop(el, container) {',
+'				var currentEl = el;',
+'				var y = 0;',
+'				while (currentEl && currentEl != container) {',
+'					y += currentEl.offsetTop;',
+'					currentEl = currentEl.offsetParent;',
+'				}',
+'				return y;',
+'			}',
+'',
+'			function scrollIntoView(el) {',
+'				var logContainer = logMainContainer;',
+'				// Check if the whole width of the element is visible and centre if not',
+'				if (!$("wrap").checked) {',
+'					var logContainerLeft = logContainer.scrollLeft;',
+'					var logContainerRight = logContainerLeft  + logContainer.offsetWidth;',
+'					var elLeft = el.offsetLeft;',
+'					var elRight = elLeft + el.offsetWidth;',
+'					if (elLeft < logContainerLeft || elRight > logContainerRight) {',
+'						logContainer.scrollLeft = elLeft - (logContainer.offsetWidth - el.offsetWidth) / 2;',
+'					}',
+'				}',
+'				// Check if the whole height of the element is visible and centre if not',
+'				var logContainerTop = logContainer.scrollTop;',
+'				var logContainerBottom = logContainerTop  + logContainer.offsetHeight;',
+'				var elTop = getPageOffsetTop(el) - getToolBarsHeight();',
+'				var elBottom = elTop + el.offsetHeight;',
+'				if (elTop < logContainerTop || elBottom > logContainerBottom) {',
+'					logContainer.scrollTop = elTop - (logContainer.offsetHeight - el.offsetHeight) / 2;',
+'				}',
+'			}',
+'',
+'			function Match(logEntryLevel, spanInMainDiv, spanInUnwrappedPre, spanInWrappedDiv) {',
+'				this.logEntryLevel = logEntryLevel;',
+'				this.spanInMainDiv = spanInMainDiv;',
+'				if (isIe) {',
+'					this.spanInUnwrappedPre = spanInUnwrappedPre;',
+'					this.spanInWrappedDiv = spanInWrappedDiv;',
+'				}',
+'				this.mainSpan = isIe ? spanInUnwrappedPre : spanInMainDiv;',
+'			}',
+'',
+'			Match.prototype = {',
+'				equals: function(match) {',
+'					return this.mainSpan === match.mainSpan;',
+'				},',
+'',
+'				setCurrent: function() {',
+'					if (isIe) {',
+'						addClass(this.spanInUnwrappedPre, "currentmatch");',
+'						addClass(this.spanInWrappedDiv, "currentmatch");',
+'						// Scroll the visible one into view',
+'						var elementToScroll = $("wrap").checked ? this.spanInWrappedDiv : this.spanInUnwrappedPre;',
+'						scrollIntoView(elementToScroll);',
+'					} else {',
+'						addClass(this.spanInMainDiv, "currentmatch");',
+'						scrollIntoView(this.spanInMainDiv);',
+'					}',
+'				},',
+'',
+'				belongsTo: function(logEntry) {',
+'					if (isIe) {',
+'						return isDescendant(this.spanInUnwrappedPre, logEntry.unwrappedPre);',
+'					} else {',
+'						return isDescendant(this.spanInMainDiv, logEntry.mainDiv);',
+'					}',
+'				},',
+'',
+'				setNotCurrent: function() {',
+'					if (isIe) {',
+'						removeClass(this.spanInUnwrappedPre, "currentmatch");',
+'						removeClass(this.spanInWrappedDiv, "currentmatch");',
+'					} else {',
+'						removeClass(this.spanInMainDiv, "currentmatch");',
+'					}',
+'				},',
+'',
+'				isOrphan: function() {',
+'					return isOrphan(this.mainSpan);',
+'				},',
+'',
+'				isVisible: function() {',
+'					return getCheckBox(this.logEntryLevel).checked;',
+'				},',
+'',
+'				remove: function() {',
+'					if (isIe) {',
+'						this.spanInUnwrappedPre = null;',
+'						this.spanInWrappedDiv = null;',
+'					} else {',
+'						this.spanInMainDiv = null;',
+'					}',
+'				}',
+'			};',
+'',
+'			var currentSearch = null;',
+'			var currentMatchIndex = null;',
+'',
+'			function doSearch() {',
+'				var searchBox = $("searchBox");',
+'				var searchTerm = searchBox.value;',
+'				var isRegex = $("searchRegex").checked;',
+'				var isCaseSensitive = $("searchCaseSensitive").checked;',
+'				var i;',
+'',
+'				if (searchTerm === "") {',
+'					$("searchReset").disabled = true;',
+'					$("searchNav").style.display = "none";',
+'					removeClass(document.body, "searching");',
+'					removeClass(searchBox, "hasmatches");',
+'					removeClass(searchBox, "nomatches");',
+'					for (i = 0; i < logEntries.length; i++) {',
+'						logEntries[i].clearSearch();',
+'						logEntries[i].setContent(logEntries[i].formattedMessage, logEntries[i].formattedMessage);',
+'					}',
+'					currentSearch = null;',
+'					setLogContainerHeight();',
+'				} else {',
+'					$("searchReset").disabled = false;',
+'					$("searchNav").style.display = "block";',
+'					var searchRegex;',
+'					var regexValid;',
+'					if (isRegex) {',
+'						try {',
+'							searchRegex = isCaseSensitive ? new RegExp(searchTerm, "g") : new RegExp(searchTerm, "gi");',
+'							regexValid = true;',
+'							replaceClass(searchBox, "validregex", "invalidregex");',
+'							searchBox.title = "Valid regex";',
+'						} catch (ex) {',
+'							regexValid = false;',
+'							replaceClass(searchBox, "invalidregex", "validregex");',
+'							searchBox.title = "Invalid regex: " + (ex.message ? ex.message : (ex.description ? ex.description : "unknown error"));',
+'							return;',
+'						}',
+'					} else {',
+'						searchBox.title = "";',
+'						removeClass(searchBox, "validregex");',
+'						removeClass(searchBox, "invalidregex");',
+'					}',
+'					addClass(document.body, "searching");',
+'					currentSearch = new Search(searchTerm, isRegex, searchRegex, isCaseSensitive);',
+'					for (i = 0; i < logEntries.length; i++) {',
+'						currentSearch.applyTo(logEntries[i]);',
+'					}',
+'					setLogContainerHeight();',
+'',
+'					// Highlight the first search match',
+'					if (currentSearch.hasVisibleMatches()) {',
+'						setCurrentMatchIndex(0);',
+'						displayMatches();',
+'					} else {',
+'						displayNoMatches();',
+'					}',
+'				}',
+'			}',
+'',
+'			function updateSearchFromFilters() {',
+'				if (currentSearch) {',
+'					if (currentSearch.hasMatches()) {',
+'						if (currentMatchIndex === null) {',
+'							currentMatchIndex = 0;',
+'						}',
+'						var currentMatch = currentSearch.matches[currentMatchIndex];',
+'						if (currentMatch.isVisible()) {',
+'							displayMatches();',
+'							setCurrentMatchIndex(currentMatchIndex);',
+'						} else {',
+'							currentMatch.setNotCurrent();',
+'							// Find the next visible match, if one exists',
+'							var nextVisibleMatchIndex = currentSearch.getNextVisibleMatchIndex();',
+'							if (nextVisibleMatchIndex > -1) {',
+'								setCurrentMatchIndex(nextVisibleMatchIndex);',
+'								displayMatches();',
+'							} else {',
+'								displayNoMatches();',
+'							}',
+'						}',
+'					} else {',
+'						displayNoMatches();',
+'					}',
+'				}',
+'			}',
+'',
+'			function refreshCurrentMatch() {',
+'				if (currentSearch && currentSearch.hasVisibleMatches()) {',
+'					setCurrentMatchIndex(currentMatchIndex);',
+'				}',
+'			}',
+'',
+'			function displayMatches() {',
+'				replaceClass($("searchBox"), "hasmatches", "nomatches");',
+'				$("searchBox").title = "" + currentSearch.matches.length + " matches found";',
+'				$("searchNav").style.display = "block";',
+'				setLogContainerHeight();',
+'			}',
+'',
+'			function displayNoMatches() {',
+'				replaceClass($("searchBox"), "nomatches", "hasmatches");',
+'				$("searchBox").title = "No matches found";',
+'				$("searchNav").style.display = "none";',
+'				setLogContainerHeight();',
+'			}',
+'',
+'			function toggleSearchEnabled(enable) {',
+'				enable = (typeof enable == "undefined") ? !$("searchDisable").checked : enable;',
+'				$("searchBox").disabled = !enable;',
+'				$("searchReset").disabled = !enable;',
+'				$("searchRegex").disabled = !enable;',
+'				$("searchNext").disabled = !enable;',
+'				$("searchPrevious").disabled = !enable;',
+'				$("searchCaseSensitive").disabled = !enable;',
+'				$("searchNav").style.display = (enable && ($("searchBox").value !== "") &&',
+'						currentSearch && currentSearch.hasVisibleMatches()) ?',
+'					"block" : "none";',
+'				if (enable) {',
+'					removeClass($("search"), "greyedout");',
+'					addClass(document.body, "searching");',
+'					if ($("searchHighlight").checked) {',
+'						addClass(logMainContainer, "searchhighlight");',
+'					} else {',
+'						removeClass(logMainContainer, "searchhighlight");',
+'					}',
+'					if ($("searchFilter").checked) {',
+'						addClass(logMainContainer, "searchfilter");',
+'					} else {',
+'						removeClass(logMainContainer, "searchfilter");',
+'					}',
+'					$("searchDisable").checked = !enable;',
+'				} else {',
+'					addClass($("search"), "greyedout");',
+'					removeClass(document.body, "searching");',
+'					removeClass(logMainContainer, "searchhighlight");',
+'					removeClass(logMainContainer, "searchfilter");',
+'				}',
+'				setLogContainerHeight();',
+'			}',
+'',
+'			function toggleSearchFilter() {',
+'				var enable = $("searchFilter").checked;',
+'				if (enable) {',
+'					addClass(logMainContainer, "searchfilter");',
+'				} else {',
+'					removeClass(logMainContainer, "searchfilter");',
+'				}',
+'				refreshCurrentMatch();',
+'			}',
+'',
+'			function toggleSearchHighlight() {',
+'				var enable = $("searchHighlight").checked;',
+'				if (enable) {',
+'					addClass(logMainContainer, "searchhighlight");',
+'				} else {',
+'					removeClass(logMainContainer, "searchhighlight");',
+'				}',
+'			}',
+'',
+'			function clearSearch() {',
+'				$("searchBox").value = "";',
+'				doSearch();',
+'			}',
+'',
+'			function searchNext() {',
+'				if (currentSearch !== null && currentMatchIndex !== null) {',
+'					currentSearch.matches[currentMatchIndex].setNotCurrent();',
+'					var nextMatchIndex = currentSearch.getNextVisibleMatchIndex();',
+'					if (nextMatchIndex > currentMatchIndex || confirm("Reached the end of the page. Start from the top?")) {',
+'						setCurrentMatchIndex(nextMatchIndex);',
+'					}',
+'				}',
+'			}',
+'',
+'			function searchPrevious() {',
+'				if (currentSearch !== null && currentMatchIndex !== null) {',
+'					currentSearch.matches[currentMatchIndex].setNotCurrent();',
+'					var previousMatchIndex = currentSearch.getPreviousVisibleMatchIndex();',
+'					if (previousMatchIndex < currentMatchIndex || confirm("Reached the start of the page. Continue from the bottom?")) {',
+'						setCurrentMatchIndex(previousMatchIndex);',
+'					}',
+'				}',
+'			}',
+'',
+'			function setCurrentMatchIndex(index) {',
+'				currentMatchIndex = index;',
+'				currentSearch.matches[currentMatchIndex].setCurrent();',
+'			}',
+'',
+'			/* ------------------------------------------------------------------------- */',
+'',
+'			// CSS Utilities',
+'',
+'			function addClass(el, cssClass) {',
+'				if (!hasClass(el, cssClass)) {',
+'					if (el.className) {',
+'						el.className += " " + cssClass;',
+'					} else {',
+'						el.className = cssClass;',
+'					}',
+'				}',
+'			}',
+'',
+'			function hasClass(el, cssClass) {',
+'				if (el.className) {',
+'					var classNames = el.className.split(" ");',
+'					return array_contains(classNames, cssClass);',
+'				}',
+'				return false;',
+'			}',
+'',
+'			function removeClass(el, cssClass) {',
+'				if (hasClass(el, cssClass)) {',
+'					// Rebuild the className property',
+'					var existingClasses = el.className.split(" ");',
+'					var newClasses = [];',
+'					for (var i = 0, len = existingClasses.length; i < len; i++) {',
+'						if (existingClasses[i] != cssClass) {',
+'							newClasses[newClasses.length] = existingClasses[i];',
+'						}',
+'					}',
+'					el.className = newClasses.join(" ");',
+'				}',
+'			}',
+'',
+'			function replaceClass(el, newCssClass, oldCssClass) {',
+'				removeClass(el, oldCssClass);',
+'				addClass(el, newCssClass);',
+'			}',
+'',
+'			/* ------------------------------------------------------------------------- */',
+'',
+'			// Other utility functions',
+'',
+'			function getElementsByClass(el, cssClass, tagName) {',
+'				var elements = el.getElementsByTagName(tagName);',
+'				var matches = [];',
+'				for (var i = 0, len = elements.length; i < len; i++) {',
+'					if (hasClass(elements[i], cssClass)) {',
+'						matches.push(elements[i]);',
+'					}',
+'				}',
+'				return matches;',
+'			}',
+'',
+'			// Syntax borrowed from Prototype library',
+'			function $(id) {',
+'				return document.getElementById(id);',
+'			}',
+'',
+'			function isDescendant(node, ancestorNode) {',
+'				while (node != null) {',
+'					if (node === ancestorNode) {',
+'						return true;',
+'					}',
+'					node = node.parentNode;',
+'				}',
+'				return false;',
+'			}',
+'',
+'			function isOrphan(node) {',
+'				var currentNode = node;',
+'				while (currentNode) {',
+'					if (currentNode == document.body) {',
+'						return false;',
+'					}',
+'					currentNode = currentNode.parentNode;',
+'				}',
+'				return true;',
+'			}',
+'',
+'			function escapeHtml(str) {',
+'				return str.replace(/&/g, "&amp;").replace(/[<]/g, "&lt;").replace(/>/g, "&gt;");',
+'			}',
+'',
+'			function getWindowWidth() {',
+'				if (window.innerWidth) {',
+'					return window.innerWidth;',
+'				} else if (document.documentElement && document.documentElement.clientWidth) {',
+'					return document.documentElement.clientWidth;',
+'				} else if (document.body) {',
+'					return document.body.clientWidth;',
+'				}',
+'				return 0;',
+'			}',
+'',
+'			function getWindowHeight() {',
+'				if (window.innerHeight) {',
+'					return window.innerHeight;',
+'				} else if (document.documentElement && document.documentElement.clientHeight) {',
+'					return document.documentElement.clientHeight;',
+'				} else if (document.body) {',
+'					return document.body.clientHeight;',
+'				}',
+'				return 0;',
+'			}',
+'',
+'			function getToolBarsHeight() {',
+'				return $("switches").offsetHeight;',
+'			}',
+'',
+'			function getChromeHeight() {',
+'				var height = getToolBarsHeight();',
+'				if (showCommandLine) {',
+'					height += $("commandLine").offsetHeight;',
+'				}',
+'				return height;',
+'			}',
+'',
+'			function setLogContainerHeight() {',
+'				if (logMainContainer) {',
+'					var windowHeight = getWindowHeight();',
+'					$("body").style.height = getWindowHeight() + "px";',
+'					logMainContainer.style.height = "" +',
+'						Math.max(0, windowHeight - getChromeHeight()) + "px";',
+'				}',
+'			}',
+'',
+'			function setCommandInputWidth() {',
+'				if (showCommandLine) {',
+'					$("command").style.width = "" + Math.max(0, $("commandLineContainer").offsetWidth -',
+'						($("evaluateButton").offsetWidth + 13)) + "px";',
+'				}',
+'			}',
+'',
+'			window.onresize = function() {',
+'				setCommandInputWidth();',
+'				setLogContainerHeight();',
+'			};',
+'',
+'			if (!Array.prototype.push) {',
+'				Array.prototype.push = function() {',
+'			        for (var i = 0, len = arguments.length; i < len; i++){',
+'			            this[this.length] = arguments[i];',
+'			        }',
+'			        return this.length;',
+'				};',
+'			}',
+'',
+'			if (!Array.prototype.pop) {',
+'				Array.prototype.pop = function() {',
+'					if (this.length > 0) {',
+'						var val = this[this.length - 1];',
+'						this.length = this.length - 1;',
+'						return val;',
+'					}',
+'				};',
+'			}',
+'',
+'			if (!Array.prototype.shift) {',
+'				Array.prototype.shift = function() {',
+'					if (this.length > 0) {',
+'						var firstItem = this[0];',
+'						for (var i = 0, len = this.length - 1; i < len; i++) {',
+'							this[i] = this[i + 1];',
+'						}',
+'						this.length = this.length - 1;',
+'						return firstItem;',
+'					}',
+'				};',
+'			}',
+'',
+'			if (!Array.prototype.splice) {',
+'				Array.prototype.splice = function(startIndex, deleteCount) {',
+'					var itemsAfterDeleted = this.slice(startIndex + deleteCount);',
+'					var itemsDeleted = this.slice(startIndex, startIndex + deleteCount);',
+'					this.length = startIndex;',
+'					// Copy the arguments into a proper Array object',
+'					var argumentsArray = [];',
+'					for (var i = 0, len = arguments.length; i < len; i++) {',
+'						argumentsArray[i] = arguments[i];',
+'					}',
+'					var itemsToAppend = (argumentsArray.length > 2) ?',
+'						itemsAfterDeleted = argumentsArray.slice(2).concat(itemsAfterDeleted) : itemsAfterDeleted;',
+'					for (i = 0, len = itemsToAppend.length; i < len; i++) {',
+'						this.push(itemsToAppend[i]);',
+'					}',
+'					return itemsDeleted;',
+'				};',
+'			}',
+'',
+'			function array_remove(arr, val) {',
+'				var index = -1;',
+'				for (var i = 0, len = arr.length; i < len; i++) {',
+'					if (arr[i] === val) {',
+'						index = i;',
+'						break;',
+'					}',
+'				}',
+'				if (index >= 0) {',
+'					arr.splice(index, 1);',
+'					return index;',
+'				} else {',
+'					return false;',
+'				}',
+'			}',
+'',
+'			function array_removeFromStart(array, numberToRemove) {',
+'				if (Array.prototype.splice) {',
+'					array.splice(0, numberToRemove);',
+'				} else {',
+'					for (var i = numberToRemove, len = array.length; i < len; i++) {',
+'						array[i - numberToRemove] = array[i];',
+'					}',
+'					array.length = array.length - numberToRemove;',
+'				}',
+'				return array;',
+'			}',
+'',
+'			function array_contains(arr, val) {',
+'				for (var i = 0, len = arr.length; i < len; i++) {',
+'					if (arr[i] == val) {',
+'						return true;',
+'					}',
+'				}',
+'				return false;',
+'			}',
+'',
+'			function getErrorMessage(ex) {',
+'				if (ex.message) {',
+'					return ex.message;',
+'				} else if (ex.description) {',
+'					return ex.description;',
+'				}',
+'				return "" + ex;',
+'			}',
+'',
+'			function moveCaretToEnd(input) {',
+'				if (input.setSelectionRange) {',
+'					input.focus();',
+'					var length = input.value.length;',
+'					input.setSelectionRange(length, length);',
+'				} else if (input.createTextRange) {',
+'					var range = input.createTextRange();',
+'					range.collapse(false);',
+'					range.select();',
+'				}',
+'				input.focus();',
+'			}',
+'',
+'			function stopPropagation(evt) {',
+'				if (evt.stopPropagation) {',
+'					evt.stopPropagation();',
+'				} else if (typeof evt.cancelBubble != "undefined") {',
+'					evt.cancelBubble = true;',
+'				}',
+'			}',
+'',
+'			function getEvent(evt) {',
+'				return evt ? evt : event;',
+'			}',
+'',
+'			function getTarget(evt) {',
+'				return evt.target ? evt.target : evt.srcElement;',
+'			}',
+'',
+'			function getRelatedTarget(evt) {',
+'				if (evt.relatedTarget) {',
+'					return evt.relatedTarget;',
+'				} else if (evt.srcElement) {',
+'					switch(evt.type) {',
+'						case "mouseover":',
+'							return evt.fromElement;',
+'						case "mouseout":',
+'							return evt.toElement;',
+'						default:',
+'							return evt.srcElement;',
+'					}',
+'				}',
+'			}',
+'',
+'			function cancelKeyEvent(evt) {',
+'				evt.returnValue = false;',
+'				stopPropagation(evt);',
+'			}',
+'',
+'			function evalCommandLine() {',
+'				var expr = $("command").value;',
+'				evalCommand(expr);',
+'				$("command").value = "";',
+'			}',
+'',
+'			function evalLastCommand() {',
+'				if (lastCommand != null) {',
+'					evalCommand(lastCommand);',
+'				}',
+'			}',
+'',
+'			var lastCommand = null;',
+'			var commandHistory = [];',
+'			var currentCommandIndex = 0;',
+'',
+'			function evalCommand(expr) {',
+'				if (appender) {',
+'					appender.evalCommandAndAppend(expr);',
+'				} else {',
+'					var prefix = ">>> " + expr + "\\r\\n";',
+'					try {',
+'						log("INFO", prefix + eval(expr));',
+'					} catch (ex) {',
+'						log("ERROR", prefix + "Error: " + getErrorMessage(ex));',
+'					}',
+'				}',
+'				// Update command history',
+'				if (expr != commandHistory[commandHistory.length - 1]) {',
+'					commandHistory.push(expr);',
+'					// Update the appender',
+'					if (appender) {',
+'						appender.storeCommandHistory(commandHistory);',
+'					}',
+'				}',
+'				currentCommandIndex = (expr == commandHistory[currentCommandIndex]) ? currentCommandIndex + 1 : commandHistory.length;',
+'				lastCommand = expr;',
+'			}',
+'			//]]>',
+'		</script>',
+'		<style type="text/css">',
+'			body {',
+'				background-color: white;',
+'				color: black;',
+'				padding: 0;',
+'				margin: 0;',
+'				font-family: tahoma, verdana, arial, helvetica, sans-serif;',
+'				overflow: hidden;',
+'			}',
+'',
+'			div#switchesContainer input {',
+'				margin-bottom: 0;',
+'			}',
+'',
+'			div.toolbar {',
+'				border-top: solid #ffffff 1px;',
+'				border-bottom: solid #aca899 1px;',
+'				background-color: #f1efe7;',
+'				padding: 3px 5px;',
+'				font-size: 68.75%;',
+'			}',
+'',
+'			div.toolbar, div#search input {',
+'				font-family: tahoma, verdana, arial, helvetica, sans-serif;',
+'			}',
+'',
+'			div.toolbar input.button {',
+'				padding: 0 5px;',
+'				font-size: 100%;',
+'			}',
+'',
+'			div.toolbar input.hidden {',
+'				display: none;',
+'			}',
+'',
+'			div#switches input#clearButton {',
+'				margin-left: 20px;',
+'			}',
+'',
+'			div#levels label {',
+'				font-weight: bold;',
+'			}',
+'',
+'			div#levels label, div#options label {',
+'				margin-right: 5px;',
+'			}',
+'',
+'			div#levels label#wrapLabel {',
+'				font-weight: normal;',
+'			}',
+'',
+'			div#search label {',
+'				margin-right: 10px;',
+'			}',
+'',
+'			div#search label.searchboxlabel {',
+'				margin-right: 0;',
+'			}',
+'',
+'			div#search input {',
+'				font-size: 100%;',
+'			}',
+'',
+'			div#search input.validregex {',
+'				color: green;',
+'			}',
+'',
+'			div#search input.invalidregex {',
+'				color: red;',
+'			}',
+'',
+'			div#search input.nomatches {',
+'				color: white;',
+'				background-color: #ff6666;',
+'			}',
+'',
+'			div#search input.nomatches {',
+'				color: white;',
+'				background-color: #ff6666;',
+'			}',
+'',
+'			div#searchNav {',
+'				display: none;',
+'			}',
+'',
+'			div#commandLine {',
+'				display: none;',
+'			}',
+'',
+'			div#commandLine input#command {',
+'				font-size: 100%;',
+'				font-family: Courier New, Courier;',
+'			}',
+'',
+'			div#commandLine input#evaluateButton {',
+'			}',
+'',
+'			*.greyedout {',
+'				color: gray !important;',
+'				border-color: gray !important;',
+'			}',
+'',
+'			*.greyedout *.alwaysenabled { color: black; }',
+'',
+'			*.unselectable {',
+'				-khtml-user-select: none;',
+'				-moz-user-select: none;',
+'				user-select: none;',
+'			}',
+'',
+'			div#log {',
+'				font-family: Courier New, Courier;',
+'				font-size: 75%;',
+'				width: 100%;',
+'				overflow: auto;',
+'				clear: both;',
+'				position: relative;',
+'			}',
+'',
+'			div.group {',
+'				border-color: #cccccc;',
+'				border-style: solid;',
+'				border-width: 1px 0 1px 1px;',
+'				overflow: visible;',
+'			}',
+'',
+'			div.oldIe div.group, div.oldIe div.group *, div.oldIe *.logentry {',
+'				height: 1%;',
+'			}',
+'',
+'			div.group div.groupheading span.expander {',
+'				border: solid black 1px;',
+'				font-family: Courier New, Courier;',
+'				font-size: 0.833em;',
+'				background-color: #eeeeee;',
+'				position: relative;',
+'				top: -1px;',
+'				color: black;',
+'				padding: 0 2px;',
+'				cursor: pointer;',
+'				cursor: hand;',
+'				height: 1%;',
+'			}',
+'',
+'			div.group div.groupcontent {',
+'				margin-left: 10px;',
+'				padding-bottom: 2px;',
+'				overflow: visible;',
+'			}',
+'',
+'			div.group div.expanded {',
+'				display: block;',
+'			}',
+'',
+'			div.group div.collapsed {',
+'				display: none;',
+'			}',
+'',
+'			*.logentry {',
+'				overflow: visible;',
+'				display: none;',
+'				white-space: pre;',
+'			}',
+'',
+'			span.pre {',
+'				white-space: pre;',
+'			}',
+'			',
+'			pre.unwrapped {',
+'				display: inline !important;',
+'			}',
+'',
+'			pre.unwrapped pre.pre, div.wrapped pre.pre {',
+'				display: inline;',
+'			}',
+'',
+'			div.wrapped pre.pre {',
+'				white-space: normal;',
+'			}',
+'',
+'			div.wrapped {',
+'				display: none;',
+'			}',
+'',
+'			body.searching *.logentry span.currentmatch {',
+'				color: white !important;',
+'				background-color: green !important;',
+'			}',
+'',
+'			body.searching div.searchhighlight *.logentry span.searchterm {',
+'				color: black;',
+'				background-color: yellow;',
+'			}',
+'',
+'			div.wrap *.logentry {',
+'				white-space: normal !important;',
+'				border-width: 0 0 1px 0;',
+'				border-color: #dddddd;',
+'				border-style: dotted;',
+'			}',
+'',
+'			div.wrap #log_wrapped, #log_unwrapped {',
+'				display: block;',
+'			}',
+'',
+'			div.wrap #log_unwrapped, #log_wrapped {',
+'				display: none;',
+'			}',
+'',
+'			div.wrap *.logentry span.pre {',
+'				overflow: visible;',
+'				white-space: normal;',
+'			}',
+'',
+'			div.wrap *.logentry pre.unwrapped {',
+'				display: none;',
+'			}',
+'',
+'			div.wrap *.logentry span.wrapped {',
+'				display: inline;',
+'			}',
+'',
+'			div.searchfilter *.searchnonmatch {',
+'				display: none !important;',
+'			}',
+'',
+'			div#log *.TRACE, label#label_TRACE {',
+'				color: #666666;',
+'			}',
+'',
+'			div#log *.DEBUG, label#label_DEBUG {',
+'				color: green;',
+'			}',
+'',
+'			div#log *.INFO, label#label_INFO {',
+'				color: #000099;',
+'			}',
+'',
+'			div#log *.WARN, label#label_WARN {',
+'				color: #999900;',
+'			}',
+'',
+'			div#log *.ERROR, label#label_ERROR {',
+'				color: red;',
+'			}',
+'',
+'			div#log *.FATAL, label#label_FATAL {',
+'				color: #660066;',
+'			}',
+'',
+'			div.TRACE#log *.TRACE,',
+'			div.DEBUG#log *.DEBUG,',
+'			div.INFO#log *.INFO,',
+'			div.WARN#log *.WARN,',
+'			div.ERROR#log *.ERROR,',
+'			div.FATAL#log *.FATAL {',
+'				display: block;',
+'			}',
+'',
+'			div#log div.separator {',
+'				background-color: #cccccc;',
+'				margin: 5px 0;',
+'				line-height: 1px;',
+'			}',
+'		</style>',
+'	</head>',
+'',
+'	<body id="body">',
+'		<div id="switchesContainer">',
+'			<div id="switches">',
+'				<div id="levels" class="toolbar">',
+'					Filters:',
+'					<input type="checkbox" id="switch_TRACE" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide trace messages" /><label for="switch_TRACE" id="label_TRACE">trace</label>',
+'					<input type="checkbox" id="switch_DEBUG" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide debug messages" /><label for="switch_DEBUG" id="label_DEBUG">debug</label>',
+'					<input type="checkbox" id="switch_INFO" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide info messages" /><label for="switch_INFO" id="label_INFO">info</label>',
+'					<input type="checkbox" id="switch_WARN" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide warn messages" /><label for="switch_WARN" id="label_WARN">warn</label>',
+'					<input type="checkbox" id="switch_ERROR" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide error messages" /><label for="switch_ERROR" id="label_ERROR">error</label>',
+'					<input type="checkbox" id="switch_FATAL" onclick="applyFilters(); checkAllLevels()" checked="checked" title="Show/hide fatal messages" /><label for="switch_FATAL" id="label_FATAL">fatal</label>',
+'					<input type="checkbox" id="switch_ALL" onclick="toggleAllLevels(); applyFilters()" checked="checked" title="Show/hide all messages" /><label for="switch_ALL" id="label_ALL">all</label>',
+'				</div>',
+'				<div id="search" class="toolbar">',
+'					<label for="searchBox" class="searchboxlabel">Search:</label> <input type="text" id="searchBox" onclick="toggleSearchEnabled(true)" onkeyup="scheduleSearch()" size="20" />',
+'					<input type="button" id="searchReset" disabled="disabled" value="Reset" onclick="clearSearch()" class="button" title="Reset the search" />',
+'					<input type="checkbox" id="searchRegex" onclick="doSearch()" title="If checked, search is treated as a regular expression" /><label for="searchRegex">Regex</label>',
+'					<input type="checkbox" id="searchCaseSensitive" onclick="doSearch()" title="If checked, search is case sensitive" /><label for="searchCaseSensitive">Match case</label>',
+'					<input type="checkbox" id="searchDisable" onclick="toggleSearchEnabled()" title="Enable/disable search" /><label for="searchDisable" class="alwaysenabled">Disable</label>',
+'					<div id="searchNav">',
+'						<input type="button" id="searchNext" disabled="disabled" value="Next" onclick="searchNext()" class="button" title="Go to the next matching log entry" />',
+'						<input type="button" id="searchPrevious" disabled="disabled" value="Previous" onclick="searchPrevious()" class="button" title="Go to the previous matching log entry" />',
+'						<input type="checkbox" id="searchFilter" onclick="toggleSearchFilter()" title="If checked, non-matching log entries are filtered out" /><label for="searchFilter">Filter</label>',
+'						<input type="checkbox" id="searchHighlight" onclick="toggleSearchHighlight()" title="Highlight matched search terms" /><label for="searchHighlight" class="alwaysenabled">Highlight all</label>',
+'					</div>',
+'				</div>',
+'				<div id="options" class="toolbar">',
+'					Options:',
+'					<input type="checkbox" id="enableLogging" onclick="toggleLoggingEnabled()" checked="checked" title="Enable/disable logging" /><label for="enableLogging" id="enableLoggingLabel">Log</label>',
+'					<input type="checkbox" id="wrap" onclick="toggleWrap()" title="Enable / disable word wrap" /><label for="wrap" id="wrapLabel">Wrap</label>',
+'					<input type="checkbox" id="newestAtTop" onclick="toggleNewestAtTop()" title="If checked, causes newest messages to appear at the top" /><label for="newestAtTop" id="newestAtTopLabel">Newest at the top</label>',
+'					<input type="checkbox" id="scrollToLatest" onclick="toggleScrollToLatest()" checked="checked" title="If checked, window automatically scrolls to a new message when it is added" /><label for="scrollToLatest" id="scrollToLatestLabel">Scroll to latest</label>',
+'					<input type="button" id="clearButton" value="Clear" onclick="clearLog()" class="button" title="Clear all log messages"  />',
+'					<input type="button" id="hideButton" value="Hide" onclick="hide()" class="hidden button" title="Hide the console" />',
+'					<input type="button" id="closeButton" value="Close" onclick="closeWindow()" class="hidden button" title="Close the window" />',
+'				</div>',
+'			</div>',
+'		</div>',
+'		<div id="log" class="TRACE DEBUG INFO WARN ERROR FATAL"></div>',
+'		<div id="commandLine" class="toolbar">',
+'			<div id="commandLineContainer">',
+'				<input type="text" id="command" title="Enter a JavaScript command here and hit return or press \'Evaluate\'" />',
+'				<input type="button" id="evaluateButton" value="Evaluate" class="button" title="Evaluate the command" onclick="evalCommandLine()" />',
+'			</div>',
+'		</div>',
+'	</body>',
+'</html>',
+''
+];
+		};
+
+		var defaultCommandLineFunctions = [];
+
+		ConsoleAppender = function() {};
+
+		var consoleAppenderIdCounter = 1;
+		ConsoleAppender.prototype = new Appender();
+
+		ConsoleAppender.prototype.create = function(inPage, container,
+				lazyInit, initiallyMinimized, useDocumentWrite, width, height, focusConsoleWindow) {
+			var appender = this;
+
+			// Common properties
+			var initialized = false;
+			var consoleWindowCreated = false;
+			var consoleWindowLoaded = false;
+			var consoleClosed = false;
+
+			var queuedLoggingEvents = [];
+			var isSupported = true;
+			var consoleAppenderId = consoleAppenderIdCounter++;
+
+			// Local variables
+			initiallyMinimized = extractBooleanFromParam(initiallyMinimized, this.defaults.initiallyMinimized);
+			lazyInit = extractBooleanFromParam(lazyInit, this.defaults.lazyInit);
+			useDocumentWrite = extractBooleanFromParam(useDocumentWrite, this.defaults.useDocumentWrite);
+			var newestMessageAtTop = this.defaults.newestMessageAtTop;
+			var scrollToLatestMessage = this.defaults.scrollToLatestMessage;
+			width = width ? width : this.defaults.width;
+			height = height ? height : this.defaults.height;
+			var maxMessages = this.defaults.maxMessages;
+			var showCommandLine = this.defaults.showCommandLine;
+			var commandLineObjectExpansionDepth = this.defaults.commandLineObjectExpansionDepth;
+			var showHideButton = this.defaults.showHideButton;
+            var showCloseButton = this.defaults.showCloseButton;
+            var showLogEntryDeleteButtons = this.defaults.showLogEntryDeleteButtons;
+
+			this.setLayout(this.defaults.layout);
+
+			// Functions whose implementations vary between subclasses
+			var init, createWindow, safeToAppend, getConsoleWindow, open;
+
+			// Configuration methods. The function scope is used to prevent
+			// direct alteration to the appender configuration properties.
+			var appenderName = inPage ? "InPageAppender" : "PopUpAppender";
+			var checkCanConfigure = function(configOptionName) {
+				if (consoleWindowCreated) {
+					handleError(appenderName + ": configuration option '" + configOptionName + "' may not be set after the appender has been initialized");
+					return false;
+				}
+				return true;
+			};
+
+			var consoleWindowExists = function() {
+				return (consoleWindowLoaded && isSupported && !consoleClosed);
+			};
+
+			this.isNewestMessageAtTop = function() { return newestMessageAtTop; };
+			this.setNewestMessageAtTop = function(newestMessageAtTopParam) {
+				newestMessageAtTop = bool(newestMessageAtTopParam);
+				if (consoleWindowExists()) {
+					getConsoleWindow().setNewestAtTop(newestMessageAtTop);
+				}
+			};
+
+			this.isScrollToLatestMessage = function() { return scrollToLatestMessage; };
+			this.setScrollToLatestMessage = function(scrollToLatestMessageParam) {
+				scrollToLatestMessage = bool(scrollToLatestMessageParam);
+				if (consoleWindowExists()) {
+					getConsoleWindow().setScrollToLatest(scrollToLatestMessage);
+				}
+			};
+
+			this.getWidth = function() { return width; };
+			this.setWidth = function(widthParam) {
+				if (checkCanConfigure("width")) {
+					width = extractStringFromParam(widthParam, width);
+				}
+			};
+
+			this.getHeight = function() { return height; };
+			this.setHeight = function(heightParam) {
+				if (checkCanConfigure("height")) {
+					height = extractStringFromParam(heightParam, height);
+				}
+			};
+
+			this.getMaxMessages = function() { return maxMessages; };
+			this.setMaxMessages = function(maxMessagesParam) {
+				maxMessages = extractIntFromParam(maxMessagesParam, maxMessages);
+				if (consoleWindowExists()) {
+					getConsoleWindow().setMaxMessages(maxMessages);
+				}
+			};
+
+			this.isShowCommandLine = function() { return showCommandLine; };
+			this.setShowCommandLine = function(showCommandLineParam) {
+				showCommandLine = bool(showCommandLineParam);
+				if (consoleWindowExists()) {
+					getConsoleWindow().setShowCommandLine(showCommandLine);
+				}
+			};
+
+			this.isShowHideButton = function() { return showHideButton; };
+			this.setShowHideButton = function(showHideButtonParam) {
+				showHideButton = bool(showHideButtonParam);
+				if (consoleWindowExists()) {
+					getConsoleWindow().setShowHideButton(showHideButton);
+				}
+			};
+
+			this.isShowCloseButton = function() { return showCloseButton; };
+			this.setShowCloseButton = function(showCloseButtonParam) {
+				showCloseButton = bool(showCloseButtonParam);
+				if (consoleWindowExists()) {
+					getConsoleWindow().setShowCloseButton(showCloseButton);
+				}
+			};
+
+			this.getCommandLineObjectExpansionDepth = function() { return commandLineObjectExpansionDepth; };
+			this.setCommandLineObjectExpansionDepth = function(commandLineObjectExpansionDepthParam) {
+				commandLineObjectExpansionDepth = extractIntFromParam(commandLineObjectExpansionDepthParam, commandLineObjectExpansionDepth);
+			};
+
+			var minimized = initiallyMinimized;
+			this.isInitiallyMinimized = function() { return initiallyMinimized; };
+			this.setInitiallyMinimized = function(initiallyMinimizedParam) {
+				if (checkCanConfigure("initiallyMinimized")) {
+					initiallyMinimized = bool(initiallyMinimizedParam);
+					minimized = initiallyMinimized;
+				}
+			};
+
+			this.isUseDocumentWrite = function() { return useDocumentWrite; };
+			this.setUseDocumentWrite = function(useDocumentWriteParam) {
+				if (checkCanConfigure("useDocumentWrite")) {
+					useDocumentWrite = bool(useDocumentWriteParam);
+				}
+			};
+
+			// Common methods
+			function QueuedLoggingEvent(loggingEvent, formattedMessage) {
+				this.loggingEvent = loggingEvent;
+				this.levelName = loggingEvent.level.name;
+				this.formattedMessage = formattedMessage;
+			}
+
+			QueuedLoggingEvent.prototype.append = function() {
+				getConsoleWindow().log(this.levelName, this.formattedMessage);
+			};
+
+			function QueuedGroup(name, initiallyExpanded) {
+				this.name = name;
+				this.initiallyExpanded = initiallyExpanded;
+			}
+
+			QueuedGroup.prototype.append = function() {
+				getConsoleWindow().group(this.name, this.initiallyExpanded);
+			};
+
+			function QueuedGroupEnd() {}
+
+			QueuedGroupEnd.prototype.append = function() {
+				getConsoleWindow().groupEnd();
+			};
+
+			var checkAndAppend = function() {
+				// Next line forces a check of whether the window has been closed
+				safeToAppend();
+				if (!initialized) {
+					init();
+				} else if (consoleClosed && reopenWhenClosed) {
+					createWindow();
+				}
+				if (safeToAppend()) {
+					appendQueuedLoggingEvents();
+				}
+			};
+
+			this.append = function(loggingEvent) {
+				if (isSupported) {
+					// Format the message
+					var formattedMessage = appender.getLayout().format(loggingEvent);
+					if (this.getLayout().ignoresThrowable()) {
+						formattedMessage += loggingEvent.getThrowableStrRep();
+					}
+					queuedLoggingEvents.push(new QueuedLoggingEvent(loggingEvent, formattedMessage));
+					checkAndAppend();
+				}
+			};
+
+            this.group = function(name, initiallyExpanded) {
+				if (isSupported) {
+					queuedLoggingEvents.push(new QueuedGroup(name, initiallyExpanded));
+					checkAndAppend();
+				}
+			};
+
+            this.groupEnd = function() {
+				if (isSupported) {
+					queuedLoggingEvents.push(new QueuedGroupEnd());
+					checkAndAppend();
+				}
+			};
+
+			var appendQueuedLoggingEvents = function() {
+				var currentLoggingEvent;
+				while (queuedLoggingEvents.length > 0) {
+					queuedLoggingEvents.shift().append();
+				}
+				if (focusConsoleWindow) {
+					getConsoleWindow().focus();
+				}
+			};
+
+			this.setAddedToLogger = function(logger) {
+				this.loggers.push(logger);
+				if (enabled && !lazyInit) {
+					init();
+				}
+			};
+
+			this.clear = function() {
+				if (consoleWindowExists()) {
+					getConsoleWindow().clearLog();
+				}
+				queuedLoggingEvents.length = 0;
+			};
+
+			this.focus = function() {
+				if (consoleWindowExists()) {
+					getConsoleWindow().focus();
+				}
+			};
+
+			this.focusCommandLine = function() {
+				if (consoleWindowExists()) {
+					getConsoleWindow().focusCommandLine();
+				}
+			};
+
+			this.focusSearch = function() {
+				if (consoleWindowExists()) {
+					getConsoleWindow().focusSearch();
+				}
+			};
+
+			var commandWindow = window;
+
+			this.getCommandWindow = function() { return commandWindow; };
+			this.setCommandWindow = function(commandWindowParam) {
+				commandWindow = commandWindowParam;
+			};
+
+			this.executeLastCommand = function() {
+				if (consoleWindowExists()) {
+					getConsoleWindow().evalLastCommand();
+				}
+			};
+
+			var commandLayout = new PatternLayout("%m");
+			this.getCommandLayout = function() { return commandLayout; };
+			this.setCommandLayout = function(commandLayoutParam) {
+				commandLayout = commandLayoutParam;
+			};
+
+			this.evalCommandAndAppend = function(expr) {
+				var commandReturnValue = { appendResult: true, isError: false };
+				var commandOutput = "";
+				// Evaluate the command
+				try {
+					var result, i;
+					// The next three lines constitute a workaround for IE. Bizarrely, iframes seem to have no
+					// eval method on the window object initially, but once execScript has been called on
+					// it once then the eval method magically appears. See http://www.thismuchiknow.co.uk/?p=25
+					if (!commandWindow.eval && commandWindow.execScript) {
+						commandWindow.execScript("null");
+					}
+
+					var commandLineFunctionsHash = {};
+					for (i = 0, len = commandLineFunctions.length; i < len; i++) {
+						commandLineFunctionsHash[commandLineFunctions[i][0]] = commandLineFunctions[i][1];
+					}
+
+					// Keep an array of variables that are being changed in the command window so that they
+					// can be restored to their original values afterwards
+					var objectsToRestore = [];
+					var addObjectToRestore = function(name) {
+						objectsToRestore.push([name, commandWindow[name]]);
+					};
+
+					addObjectToRestore("appender");
+					commandWindow.appender = appender;
+
+					addObjectToRestore("commandReturnValue");
+					commandWindow.commandReturnValue = commandReturnValue;
+
+					addObjectToRestore("commandLineFunctionsHash");
+					commandWindow.commandLineFunctionsHash = commandLineFunctionsHash;
+
+					var addFunctionToWindow = function(name) {
+						addObjectToRestore(name);
+						commandWindow[name] = function() {
+							return this.commandLineFunctionsHash[name](appender, arguments, commandReturnValue);
+						};
+					};
+
+					for (i = 0, len = commandLineFunctions.length; i < len; i++) {
+						addFunctionToWindow(commandLineFunctions[i][0]);
+					}
+
+					// Another bizarre workaround to get IE to eval in the global scope
+					if (commandWindow === window && commandWindow.execScript) {
+						addObjectToRestore("evalExpr");
+						addObjectToRestore("result");
+						window.evalExpr = expr;
+						commandWindow.execScript("window.result=eval(window.evalExpr);");
+						result = window.result;
+ 					} else {
+ 						result = commandWindow.eval(expr);
+ 					}
+					commandOutput = isUndefined(result) ? result : formatObjectExpansion(result, commandLineObjectExpansionDepth);
+
+					// Restore variables in the command window to their original state
+					for (i = 0, len = objectsToRestore.length; i < len; i++) {
+						commandWindow[objectsToRestore[i][0]] = objectsToRestore[i][1];
+					}
+				} catch (ex) {
+					commandOutput = "Error evaluating command: " + getExceptionStringRep(ex);
+					commandReturnValue.isError = true;
+				}
+				// Append command output
+				if (commandReturnValue.appendResult) {
+					var message = ">>> " + expr;
+					if (!isUndefined(commandOutput)) {
+						message += newLine + commandOutput;
+					}
+					var level = commandReturnValue.isError ? Level.ERROR : Level.INFO;
+					var loggingEvent = new LoggingEvent(null, new Date(), level, [message], null);
+					var mainLayout = this.getLayout();
+					this.setLayout(commandLayout);
+					this.append(loggingEvent);
+					this.setLayout(mainLayout);
+				}
+			};
+
+			var commandLineFunctions = defaultCommandLineFunctions.concat([]);
+
+			this.addCommandLineFunction = function(functionName, commandLineFunction) {
+				commandLineFunctions.push([functionName, commandLineFunction]);
+			};
+
+			var commandHistoryCookieName = "log4javascriptCommandHistory";
+			this.storeCommandHistory = function(commandHistory) {
+				setCookie(commandHistoryCookieName, commandHistory.join(","));
+			};
+
+			var writeHtml = function(doc) {
+				var lines = getConsoleHtmlLines();
+				doc.open();
+				for (var i = 0, len = lines.length; i < len; i++) {
+					doc.writeln(lines[i]);
+				}
+				doc.close();
+			};
+
+			// Set up event listeners
+			this.setEventTypes(["load", "unload"]);
+
+			var consoleWindowLoadHandler = function() {
+				var win = getConsoleWindow();
+				win.setAppender(appender);
+				win.setNewestAtTop(newestMessageAtTop);
+				win.setScrollToLatest(scrollToLatestMessage);
+				win.setMaxMessages(maxMessages);
+				win.setShowCommandLine(showCommandLine);
+				win.setShowHideButton(showHideButton);
+				win.setShowCloseButton(showCloseButton);
+				win.setMainWindow(window);
+
+				// Restore command history stored in cookie
+				var storedValue = getCookie(commandHistoryCookieName);
+				if (storedValue) {
+					win.commandHistory = storedValue.split(",");
+					win.currentCommandIndex = win.commandHistory.length;
+				}
+
+				appender.dispatchEvent("load", { "win" : win });
+			};
+
+			this.unload = function() {
+				logLog.debug("unload " + this + ", caller: " + this.unload.caller);
+				if (!consoleClosed) {
+					logLog.debug("really doing unload " + this);
+					consoleClosed = true;
+					consoleWindowLoaded = false;
+					consoleWindowCreated = false;
+					appender.dispatchEvent("unload", {});
+				}
+			};
+
+			var pollConsoleWindow = function(windowTest, interval, successCallback, errorMessage) {
+				function doPoll() {
+					try {
+						// Test if the console has been closed while polling
+						if (consoleClosed) {
+							clearInterval(poll);
+						}
+						if (windowTest(getConsoleWindow())) {
+							clearInterval(poll);
+							successCallback();
+						}
+					} catch (ex) {
+						clearInterval(poll);
+						isSupported = false;
+						handleError(errorMessage, ex);
+					}
+				}
+
+				// Poll the pop-up since the onload event is not reliable
+				var poll = setInterval(doPoll, interval);
+			};
+
+			var getConsoleUrl = function() {
+				var documentDomainSet = (document.domain != location.hostname);
+				return useDocumentWrite ? "" : getBaseUrl() + "console_uncompressed.html" +
+											   (documentDomainSet ? "?log4javascript_domain=" + escape(document.domain) : "");
+			};
+
+			// Define methods and properties that vary between subclasses
+			if (inPage) {
+				// InPageAppender
+
+				var containerElement = null;
+
+				// Configuration methods. The function scope is used to prevent
+				// direct alteration to the appender configuration properties.
+				var cssProperties = [];
+				this.addCssProperty = function(name, value) {
+					if (checkCanConfigure("cssProperties")) {
+						cssProperties.push([name, value]);
+					}
+				};
+
+				// Define useful variables
+				var windowCreationStarted = false;
+				var iframeContainerDiv;
+				var iframeId = uniqueId + "_InPageAppender_" + consoleAppenderId;
+
+				this.hide = function() {
+					if (initialized && consoleWindowCreated) {
+						if (consoleWindowExists()) {
+							getConsoleWindow().$("command").blur();
+						}
+						iframeContainerDiv.style.display = "none";
+						minimized = true;
+					}
+				};
+
+				this.show = function() {
+					if (initialized) {
+						if (consoleWindowCreated) {
+							iframeContainerDiv.style.display = "block";
+							this.setShowCommandLine(showCommandLine); // Force IE to update
+							minimized = false;
+						} else if (!windowCreationStarted) {
+							createWindow(true);
+						}
+					}
+				};
+
+				this.isVisible = function() {
+					return !minimized && !consoleClosed;
+				};
+
+				this.close = function(fromButton) {
+					if (!consoleClosed && (!fromButton || confirm("This will permanently remove the console from the page. No more messages will be logged. Do you wish to continue?"))) {
+						iframeContainerDiv.parentNode.removeChild(iframeContainerDiv);
+						this.unload();
+					}
+				};
+
+				// Create open, init, getConsoleWindow and safeToAppend functions
+				open = function() {
+					var initErrorMessage = "InPageAppender.open: unable to create console iframe";
+
+					function finalInit() {
+						try {
+							if (!initiallyMinimized) {
+								appender.show();
+							}
+							consoleWindowLoadHandler();
+							consoleWindowLoaded = true;
+							appendQueuedLoggingEvents();
+						} catch (ex) {
+							isSupported = false;
+							handleError(initErrorMessage, ex);
+						}
+					}
+
+					function writeToDocument() {
+						try {
+							var windowTest = function(win) { return isLoaded(win); };
+							if (useDocumentWrite) {
+								writeHtml(getConsoleWindow().document);
+							}
+							if (windowTest(getConsoleWindow())) {
+								finalInit();
+							} else {
+								pollConsoleWindow(windowTest, 100, finalInit, initErrorMessage);
+							}
+						} catch (ex) {
+							isSupported = false;
+							handleError(initErrorMessage, ex);
+						}
+					}
+
+					minimized = false;
+					iframeContainerDiv = containerElement.appendChild(document.createElement("div"));
+
+					iframeContainerDiv.style.width = width;
+					iframeContainerDiv.style.height = height;
+					iframeContainerDiv.style.border = "solid gray 1px";
+
+					for (var i = 0, len = cssProperties.length; i < len; i++) {
+						iframeContainerDiv.style[cssProperties[i][0]] = cssProperties[i][1];
+					}
+
+					var iframeSrc = useDocumentWrite ? "" : " src='" + getConsoleUrl() + "'";
+
+					// Adding an iframe using the DOM would be preferable, but it doesn't work
+					// in IE5 on Windows, or in Konqueror prior to version 3.5 - in Konqueror
+					// it creates the iframe fine but I haven't been able to find a way to obtain
+					// the iframe's window object
+					iframeContainerDiv.innerHTML = "<iframe id='" + iframeId + "' name='" + iframeId +
+						"' width='100%' height='100%' frameborder='0'" + iframeSrc +
+						" scrolling='no'></iframe>";
+					consoleClosed = false;
+
+					// Write the console HTML to the iframe
+					var iframeDocumentExistsTest = function(win) {
+						try {
+							return bool(win) && bool(win.document);
+						} catch (ex) {
+							return false;
+						}
+					};
+					if (iframeDocumentExistsTest(getConsoleWindow())) {
+						writeToDocument();
+					} else {
+						pollConsoleWindow(iframeDocumentExistsTest, 100, writeToDocument, initErrorMessage);
+					}
+					consoleWindowCreated = true;
+				};
+
+				createWindow = function(show) {
+					if (show || !initiallyMinimized) {
+						var pageLoadHandler = function() {
+							if (!container) {
+								// Set up default container element
+								containerElement = document.createElement("div");
+								containerElement.style.position = "fixed";
+								containerElement.style.left = "0";
+								containerElement.style.right = "0";
+								containerElement.style.bottom = "0";
+								document.body.appendChild(containerElement);
+								appender.addCssProperty("borderWidth", "1px 0 0 0");
+								appender.addCssProperty("zIndex", 1000000); // Can't find anything authoritative that says how big z-index can be
+								open();
+							} else {
+								try {
+									var el = document.getElementById(container);
+									if (el.nodeType == 1) {
+										containerElement = el;
+									}
+									open();
+								} catch (ex) {
+									handleError("InPageAppender.init: invalid container element '" + container + "' supplied", ex);
+								}
+							}
+						};
+
+						// Test the type of the container supplied. First, check if it's an element
+						if (pageLoaded && container && container.appendChild) {
+							containerElement = container;
+							open();
+						} else if (pageLoaded) {
+							pageLoadHandler();
+						} else {
+							log4javascript.addEventListener("load", pageLoadHandler);
+						}
+						windowCreationStarted = true;
+					}
+				};
+
+				init = function() {
+					createWindow();
+					initialized = true;
+				};
+
+				getConsoleWindow = function() {
+					var iframe = window.frames[iframeId];
+					if (iframe) {
+						return iframe;
+					}
+				};
+
+				safeToAppend = function() {
+					if (isSupported && !consoleClosed) {
+						if (consoleWindowCreated && !consoleWindowLoaded && getConsoleWindow() && isLoaded(getConsoleWindow())) {
+							consoleWindowLoaded = true;
+						}
+						return consoleWindowLoaded;
+					}
+					return false;
+				};
+			} else {
+				// PopUpAppender
+
+				// Extract params
+				var useOldPopUp = appender.defaults.useOldPopUp;
+				var complainAboutPopUpBlocking = appender.defaults.complainAboutPopUpBlocking;
+				var reopenWhenClosed = this.defaults.reopenWhenClosed;
+
+				// Configuration methods. The function scope is used to prevent
+				// direct alteration to the appender configuration properties.
+				this.isUseOldPopUp = function() { return useOldPopUp; };
+				this.setUseOldPopUp = function(useOldPopUpParam) {
+					if (checkCanConfigure("useOldPopUp")) {
+						useOldPopUp = bool(useOldPopUpParam);
+					}
+				};
+
+				this.isComplainAboutPopUpBlocking = function() { return complainAboutPopUpBlocking; };
+				this.setComplainAboutPopUpBlocking = function(complainAboutPopUpBlockingParam) {
+					if (checkCanConfigure("complainAboutPopUpBlocking")) {
+						complainAboutPopUpBlocking = bool(complainAboutPopUpBlockingParam);
+					}
+				};
+
+				this.isFocusPopUp = function() { return focusConsoleWindow; };
+				this.setFocusPopUp = function(focusPopUpParam) {
+					// This property can be safely altered after logging has started
+					focusConsoleWindow = bool(focusPopUpParam);
+				};
+
+				this.isReopenWhenClosed = function() { return reopenWhenClosed; };
+				this.setReopenWhenClosed = function(reopenWhenClosedParam) {
+					// This property can be safely altered after logging has started
+					reopenWhenClosed = bool(reopenWhenClosedParam);
+				};
+
+				this.close = function() {
+					logLog.debug("close " + this);
+					try {
+						popUp.close();
+						this.unload();
+					} catch (ex) {
+						// Do nothing
+					}
+				};
+
+				this.hide = function() {
+					logLog.debug("hide " + this);
+					if (consoleWindowExists()) {
+						this.close();
+					}
+				};
+
+				this.show = function() {
+					logLog.debug("show " + this);
+					if (!consoleWindowCreated) {
+						open();
+					}
+				};
+
+				this.isVisible = function() {
+					return safeToAppend();
+				};
+
+				// Define useful variables
+				var popUp;
+
+				// Create open, init, getConsoleWindow and safeToAppend functions
+				open = function() {
+					var windowProperties = "width=" + width + ",height=" + height + ",status,resizable";
+					var frameInfo = "";
+					try {
+						var frameEl = window.frameElement;
+						if (frameEl) {
+							frameInfo = "_" + frameEl.tagName + "_" + (frameEl.name || frameEl.id || "");
+						}
+					} catch (e) {
+						frameInfo = "_inaccessibleParentFrame";
+					}
+					var windowName = "PopUp_" + location.host.replace(/[^a-z0-9]/gi, "_") + "_" + consoleAppenderId + frameInfo;
+					if (!useOldPopUp || !useDocumentWrite) {
+						// Ensure a previous window isn't used by using a unique name
+						windowName = windowName + "_" + uniqueId;
+					}
+
+					var checkPopUpClosed = function(win) {
+						if (consoleClosed) {
+							return true;
+						} else {
+							try {
+								return bool(win) && win.closed;
+							} catch(ex) {}
+						}
+						return false;
+					};
+
+					var popUpClosedCallback = function() {
+						if (!consoleClosed) {
+							appender.unload();
+						}
+					};
+
+					function finalInit() {
+						getConsoleWindow().setCloseIfOpenerCloses(!useOldPopUp || !useDocumentWrite);
+						consoleWindowLoadHandler();
+						consoleWindowLoaded = true;
+						appendQueuedLoggingEvents();
+						pollConsoleWindow(checkPopUpClosed, 500, popUpClosedCallback,
+								"PopUpAppender.checkPopUpClosed: error checking pop-up window");
+					}
+
+					try {
+						popUp = window.open(getConsoleUrl(), windowName, windowProperties);
+						consoleClosed = false;
+						consoleWindowCreated = true;
+						if (popUp && popUp.document) {
+							if (useDocumentWrite && useOldPopUp && isLoaded(popUp)) {
+								popUp.mainPageReloaded();
+								finalInit();
+							} else {
+								if (useDocumentWrite) {
+									writeHtml(popUp.document);
+								}
+								// Check if the pop-up window object is available
+								var popUpLoadedTest = function(win) { return bool(win) && isLoaded(win); };
+								if (isLoaded(popUp)) {
+									finalInit();
+								} else {
+									pollConsoleWindow(popUpLoadedTest, 100, finalInit,
+											"PopUpAppender.init: unable to create console window");
+								}
+							}
+						} else {
+							isSupported = false;
+							logLog.warn("PopUpAppender.init: pop-ups blocked, please unblock to use PopUpAppender");
+							if (complainAboutPopUpBlocking) {
+								handleError("log4javascript: pop-up windows appear to be blocked. Please unblock them to use pop-up logging.");
+							}
+						}
+					} catch (ex) {
+						handleError("PopUpAppender.init: error creating pop-up", ex);
+					}
+				};
+
+				createWindow = function() {
+					if (!initiallyMinimized) {
+						open();
+					}
+				};
+
+				init = function() {
+					createWindow();
+					initialized = true;
+				};
+
+				getConsoleWindow = function() {
+					return popUp;
+				};
+
+				safeToAppend = function() {
+					if (isSupported && !isUndefined(popUp) && !consoleClosed) {
+						if (popUp.closed ||
+								(consoleWindowLoaded && isUndefined(popUp.closed))) { // Extra check for Opera
+							appender.unload();
+							logLog.debug("PopUpAppender: pop-up closed");
+							return false;
+						}
+						if (!consoleWindowLoaded && isLoaded(popUp)) {
+							consoleWindowLoaded = true;
+						}
+					}
+					return isSupported && consoleWindowLoaded && !consoleClosed;
+				};
+			}
+
+			// Expose getConsoleWindow so that automated tests can check the DOM
+			this.getConsoleWindow = getConsoleWindow;
+		};
+
+		ConsoleAppender.addGlobalCommandLineFunction = function(functionName, commandLineFunction) {
+			defaultCommandLineFunctions.push([functionName, commandLineFunction]);
+		};
+
+		/* ------------------------------------------------------------------ */
+
+		function PopUpAppender(lazyInit, initiallyMinimized, useDocumentWrite,
+							   width, height) {
+			this.create(false, null, lazyInit, initiallyMinimized,
+					useDocumentWrite, width, height, this.defaults.focusPopUp);
+		}
+
+		PopUpAppender.prototype = new ConsoleAppender();
+
+		PopUpAppender.prototype.defaults = {
+			layout: new PatternLayout("%d{HH:mm:ss} %-5p - %m{1}%n"),
+			initiallyMinimized: false,
+			focusPopUp: false,
+			lazyInit: true,
+			useOldPopUp: true,
+			complainAboutPopUpBlocking: true,
+			newestMessageAtTop: false,
+			scrollToLatestMessage: true,
+			width: "600",
+			height: "400",
+			reopenWhenClosed: false,
+			maxMessages: null,
+			showCommandLine: true,
+			commandLineObjectExpansionDepth: 1,
+			showHideButton: false,
+			showCloseButton: true,
+            showLogEntryDeleteButtons: true,
+            useDocumentWrite: true
+		};
+
+		PopUpAppender.prototype.toString = function() {
+			return "PopUpAppender";
+		};
+
+		log4javascript.PopUpAppender = PopUpAppender;
+
+		/* ------------------------------------------------------------------ */
+
+		function InPageAppender(container, lazyInit, initiallyMinimized,
+								useDocumentWrite, width, height) {
+			this.create(true, container, lazyInit, initiallyMinimized,
+					useDocumentWrite, width, height, false);
+		}
+
+		InPageAppender.prototype = new ConsoleAppender();
+
+		InPageAppender.prototype.defaults = {
+			layout: new PatternLayout("%d{HH:mm:ss} %-5p - %m{1}%n"),
+			initiallyMinimized: false,
+			lazyInit: true,
+			newestMessageAtTop: false,
+			scrollToLatestMessage: true,
+			width: "100%",
+			height: "220px",
+			maxMessages: null,
+			showCommandLine: true,
+			commandLineObjectExpansionDepth: 1,
+			showHideButton: false,
+			showCloseButton: false,
+            showLogEntryDeleteButtons: true,
+            useDocumentWrite: true
+		};
+
+		InPageAppender.prototype.toString = function() {
+			return "InPageAppender";
+		};
+
+		log4javascript.InPageAppender = InPageAppender;
+
+		// Next line for backwards compatibility
+		log4javascript.InlineAppender = InPageAppender;
+	})();
+	/* ---------------------------------------------------------------------- */
+	// Console extension functions
+
+	function padWithSpaces(str, len) {
+		if (str.length < len) {
+			var spaces = [];
+			var numberOfSpaces = Math.max(0, len - str.length);
+			for (var i = 0; i < numberOfSpaces; i++) {
+				spaces[i] = " ";
+			}
+			str += spaces.join("");
+		}
+		return str;
+	}
+
+	(function() {
+		function dir(obj) {
+			var maxLen = 0;
+			// Obtain the length of the longest property name
+			for (var p in obj) {
+				maxLen = Math.max(toStr(p).length, maxLen);
+			}
+			// Create the nicely formatted property list
+			var propList = [];
+			for (p in obj) {
+				var propNameStr = "  " + padWithSpaces(toStr(p), maxLen + 2);
+				var propVal;
+				try {
+					propVal = splitIntoLines(toStr(obj[p])).join(padWithSpaces(newLine, maxLen + 6));
+				} catch (ex) {
+					propVal = "[Error obtaining property. Details: " + getExceptionMessage(ex) + "]";
+				}
+				propList.push(propNameStr + propVal);
+			}
+			return propList.join(newLine);
+		}
+
+		var nodeTypes = {
+			ELEMENT_NODE: 1,
+			ATTRIBUTE_NODE: 2,
+			TEXT_NODE: 3,
+			CDATA_SECTION_NODE: 4,
+			ENTITY_REFERENCE_NODE: 5,
+			ENTITY_NODE: 6,
+			PROCESSING_INSTRUCTION_NODE: 7,
+			COMMENT_NODE: 8,
+			DOCUMENT_NODE: 9,
+			DOCUMENT_TYPE_NODE: 10,
+			DOCUMENT_FRAGMENT_NODE: 11,
+			NOTATION_NODE: 12
+		};
+
+		var preFormattedElements = ["script", "pre"];
+
+		// This should be the definitive list, as specified by the XHTML 1.0 Transitional DTD
+		var emptyElements = ["br", "img", "hr", "param", "link", "area", "input", "col", "base", "meta"];
+		var indentationUnit = "  ";
+
+		// Create and return an XHTML string from the node specified
+		function getXhtml(rootNode, includeRootNode, indentation, startNewLine, preformatted) {
+			includeRootNode = (typeof includeRootNode == "undefined") ? true : !!includeRootNode;
+			if (typeof indentation != "string") {
+				indentation = "";
+			}
+			startNewLine = !!startNewLine;
+			preformatted = !!preformatted;
+			var xhtml;
+
+			function isWhitespace(node) {
+				return ((node.nodeType == nodeTypes.TEXT_NODE) && /^[ \t\r\n]*$/.test(node.nodeValue));
+			}
+
+			function fixAttributeValue(attrValue) {
+				return attrValue.toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/"/g, "&quot;");
+			}
+
+			function getStyleAttributeValue(el) {
+				var stylePairs = el.style.cssText.split(";");
+				var styleValue = "";
+				var isFirst = true;
+				for (var j = 0, len = stylePairs.length; j < len; j++) {
+					var nameValueBits = stylePairs[j].split(":");
+					var props = [];
+					if (!/^\s*$/.test(nameValueBits[0])) {
+						props.push(trim(nameValueBits[0]).toLowerCase() + ":" + trim(nameValueBits[1]));
+					}
+					styleValue = props.join(";");
+				}
+				return styleValue;
+			}
+
+			function getNamespace(el) {
+				if (el.prefix) {
+					return el.prefix;
+				} else if (el.outerHTML) {
+					var regex = new RegExp("<([^:]+):" + el.tagName + "[^>]*>", "i");
+					if (regex.test(el.outerHTML)) {
+						return RegExp.$1.toLowerCase();
+					}
+				}
+                return "";
+			}
+
+			var lt = "<";
+			var gt = ">";
+
+			if (includeRootNode && rootNode.nodeType != nodeTypes.DOCUMENT_FRAGMENT_NODE) {
+				switch (rootNode.nodeType) {
+					case nodeTypes.ELEMENT_NODE:
+						var tagName = rootNode.tagName.toLowerCase();
+						xhtml = startNewLine ? newLine + indentation : "";
+						xhtml += lt;
+						// Allow for namespaces, where present
+						var prefix = getNamespace(rootNode);
+						var hasPrefix = !!prefix;
+						if (hasPrefix) {
+							xhtml += prefix + ":";
+						}
+						xhtml += tagName;
+						for (i = 0, len = rootNode.attributes.length; i < len; i++) {
+							var currentAttr = rootNode.attributes[i];
+							// Check the attribute is valid.
+							if (!	currentAttr.specified ||
+									currentAttr.nodeValue === null ||
+									currentAttr.nodeName.toLowerCase() === "style" ||
+									typeof currentAttr.nodeValue !== "string" ||
+									currentAttr.nodeName.indexOf("_moz") === 0) {
+								continue;
+							}
+							xhtml += " " + currentAttr.nodeName.toLowerCase() + "=\"";
+							xhtml += fixAttributeValue(currentAttr.nodeValue);
+							xhtml += "\"";
+						}
+						// Style needs to be done separately as it is not reported as an
+						// attribute in IE
+						if (rootNode.style.cssText) {
+							var styleValue = getStyleAttributeValue(rootNode);
+							if (styleValue !== "") {
+								xhtml += " style=\"" + getStyleAttributeValue(rootNode) + "\"";
+							}
+						}
+						if (array_contains(emptyElements, tagName) ||
+								(hasPrefix && !rootNode.hasChildNodes())) {
+							xhtml += "/" + gt;
+						} else {
+							xhtml += gt;
+							// Add output for childNodes collection (which doesn't include attribute nodes)
+							var childStartNewLine = !(rootNode.childNodes.length === 1 &&
+								rootNode.childNodes[0].nodeType === nodeTypes.TEXT_NODE);
+							var childPreformatted = array_contains(preFormattedElements, tagName);
+							for (var i = 0, len = rootNode.childNodes.length; i < len; i++) {
+								xhtml += getXhtml(rootNode.childNodes[i], true, indentation + indentationUnit,
+									childStartNewLine, childPreformatted);
+							}
+							// Add the end tag
+							var endTag = lt + "/" + tagName + gt;
+							xhtml += childStartNewLine ? newLine + indentation + endTag : endTag;
+						}
+						return xhtml;
+					case nodeTypes.TEXT_NODE:
+						if (isWhitespace(rootNode)) {
+							xhtml = "";
+						} else {
+							if (preformatted) {
+								xhtml = rootNode.nodeValue;
+							} else {
+								// Trim whitespace from each line of the text node
+								var lines = splitIntoLines(trim(rootNode.nodeValue));
+								var trimmedLines = [];
+								for (var i = 0, len = lines.length; i < len; i++) {
+									trimmedLines[i] = trim(lines[i]);
+								}
+								xhtml = trimmedLines.join(newLine + indentation);
+							}
+							if (startNewLine) {
+								xhtml = newLine + indentation + xhtml;
+							}
+						}
+						return xhtml;
+					case nodeTypes.CDATA_SECTION_NODE:
+						return "<![CDA" + "TA[" + rootNode.nodeValue + "]" + "]>" + newLine;
+					case nodeTypes.DOCUMENT_NODE:
+						xhtml = "";
+						// Add output for childNodes collection (which doesn't include attribute nodes)
+						for (var i = 0, len = rootNode.childNodes.length; i < len; i++) {
+							xhtml += getXhtml(rootNode.childNodes[i], true, indentation);
+						}
+						return xhtml;
+					default:
+						return "";
+				}
+			} else {
+				xhtml = "";
+				// Add output for childNodes collection (which doesn't include attribute nodes)
+				for (var i = 0, len = rootNode.childNodes.length; i < len; i++) {
+					xhtml += getXhtml(rootNode.childNodes[i], true, indentation + indentationUnit);
+				}
+				return xhtml;
+			}
+		}
+
+		function createCommandLineFunctions() {
+			ConsoleAppender.addGlobalCommandLineFunction("$", function(appender, args, returnValue) {
+				return document.getElementById(args[0]);
+			});
+
+			ConsoleAppender.addGlobalCommandLineFunction("dir", function(appender, args, returnValue) {
+				var lines = [];
+				for (var i = 0, len = args.length; i < len; i++) {
+					lines[i] = dir(args[i]);
+				}
+				return lines.join(newLine + newLine);
+			});
+
+			ConsoleAppender.addGlobalCommandLineFunction("dirxml", function(appender, args, returnValue) {
+				var lines = [];
+				for (var i = 0, len = args.length; i < len; i++) {
+					var win = appender.getCommandWindow();
+					lines[i] = getXhtml(args[i]);
+				}
+				return lines.join(newLine + newLine);
+			});
+
+			ConsoleAppender.addGlobalCommandLineFunction("cd", function(appender, args, returnValue) {
+				var win, message;
+				if (args.length === 0 || args[0] === "") {
+					win = window;
+					message = "Command line set to run in main window";
+				} else {
+					if (args[0].window == args[0]) {
+						win = args[0];
+						message = "Command line set to run in frame '" + args[0].name + "'";
+					} else {
+						win = window.frames[args[0]];
+						if (win) {
+							message = "Command line set to run in frame '" + args[0] + "'";
+						} else {
+							returnValue.isError = true;
+							message = "Frame '" + args[0] + "' does not exist";
+							win = appender.getCommandWindow();
+						}
+					}
+				}
+				appender.setCommandWindow(win);
+				return message;
+			});
+
+			ConsoleAppender.addGlobalCommandLineFunction("clear", function(appender, args, returnValue) {
+				returnValue.appendResult = false;
+				appender.clear();
+			});
+
+			ConsoleAppender.addGlobalCommandLineFunction("keys", function(appender, args, returnValue) {
+				var keys = [];
+				for (var k in args[0]) {
+					keys.push(k);
+				}
+				return keys;
+			});
+
+			ConsoleAppender.addGlobalCommandLineFunction("values", function(appender, args, returnValue) {
+				var values = [];
+				for (var k in args[0]) {
+					try {
+						values.push(args[0][k]);
+					} catch (ex) {
+						logLog.warn("values(): Unable to obtain value for key " + k + ". Details: " + getExceptionMessage(ex));
+					}
+				}
+				return values;
+			});
+
+			ConsoleAppender.addGlobalCommandLineFunction("expansionDepth", function(appender, args, returnValue) {
+				var expansionDepth = parseInt(args[0], 10);
+				if (isNaN(expansionDepth) || expansionDepth < 0) {
+					returnValue.isError = true;
+					return "" + args[0] + " is not a valid expansion depth";
+				} else {
+					appender.setCommandLineObjectExpansionDepth(expansionDepth);
+					return "Object expansion depth set to " + expansionDepth;
+				}
+			});
+		}
+
+		function init() {
+			// Add command line functions
+			createCommandLineFunctions();
+		}
+
+		/* ------------------------------------------------------------------ */
+
+		init();
+	})();
+
+	/* ---------------------------------------------------------------------- */
+	// Main load
+
+   log4javascript.setDocumentReady = function() {
+       pageLoaded = true;
+       log4javascript.dispatchEvent("load", {});
+   };
+
+    if (window.addEventListener) {
+        window.addEventListener("load", log4javascript.setDocumentReady, false);
+    } else if (window.attachEvent) {
+        window.attachEvent("onload", log4javascript.setDocumentReady);
+    } else {
+        var oldOnload = window.onload;
+        if (typeof window.onload != "function") {
+            window.onload = log4javascript.setDocumentReady;
+        } else {
+            window.onload = function(evt) {
+                if (oldOnload) {
+                    oldOnload(evt);
+                }
+                log4javascript.setDocumentReady();
+            };
+        }
+    }
+
+    // Ensure that the log4javascript object is available in the window. This
+    // is necessary for log4javascript to be available in IE if loaded using
+    // Dojo's module system
+    window.log4javascript = log4javascript;
+
+    return log4javascript;
+})();
\ No newline at end of file
