diff --git a/planetstack/core/static/log4javascript-1.4.6/test/xntest.js b/planetstack/core/static/log4javascript-1.4.6/test/xntest.js
new file mode 100644
index 0000000..1b8f475
--- /dev/null
+++ b/planetstack/core/static/log4javascript-1.4.6/test/xntest.js
@@ -0,0 +1,739 @@
+// Next three methods are primarily for IE5, which is missing them
+if (!Array.prototype.push) {
+	Array.prototype.push = function() {
+		for (var i = 0; i < arguments.length; 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; i < this.length - 1; i++) {
+				this[i] = this[i + 1];
+			}
+			this.length = this.length - 1;
+			return firstItem;
+		}
+	};
+}
+
+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 = new Array(args.length);
+		for (var i = 0; i < args.length; i++) {
+			argsStrings[i] = "args[" + i + "]";
+		}
+		var script = "obj." + methodName + "(" + argsStrings.join(",") + ")";
+		var returnValue = eval(script);
+		delete obj[methodName];
+		return returnValue;
+	};
+}
+
+/* -------------------------------------------------------------------------- */
+
+var xn = new Object();
+
+(function() {
+	// Utility functions
+
+	// Event listeners
+	var getListenersPropertyName = function(eventName) {
+		return "__listeners__" + eventName;
+	};
+
+	var addEventListener = function(node, eventName, listener, useCapture) {
+		useCapture = Boolean(useCapture);
+		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] = new Array();
+
+				// Set event handler
+				node["on" + eventName] = function(evt) {
+					evt = module.getEvent(evt);
+					var listenersPropertyName = getListenersPropertyName(eventName);
+
+					// Clone the array of listeners to leave the original untouched
+					var listeners = cloneArray(this[listenersPropertyName]);
+					var currentListener;
+
+					// Call each listener in turn
+					while (currentListener = listeners.shift()) {
+						currentListener.call(this, evt);
+					}
+				};
+			}
+			node[propertyName].push(listener);
+		}
+	};
+
+	// Clones an array
+	var cloneArray = function(arr) {
+		var clonedArray = [];
+		for (var i = 0; i < arr.length; i++) {
+			clonedArray[i] = arr[i];
+		}
+		return clonedArray;
+	}
+
+	var isFunction = function(f) {
+		if (!f){ return false; }
+		return (f instanceof Function || typeof f == "function");
+	};
+
+	// CSS Utilities
+	
+	function array_contains(arr, val) {
+		for (var i = 0, len = arr.length; i < len; i++) {
+			if (arr[i] === val) {
+				return true;
+			}
+		}
+		return false;
+	}
+
+	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; i < existingClasses.length; 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);
+	}
+
+	function getExceptionStringRep(ex) {
+		if (ex) {
+			var exStr = "Exception: ";
+			if (ex.message) {
+				exStr += ex.message;
+			} else if (ex.description) {
+				exStr += ex.description;
+			}
+			if (ex.lineNumber) {
+				exStr += " on line number " + ex.lineNumber;
+			}
+			if (ex.fileName) {
+				exStr += " in file " + ex.fileName;
+			}
+			return exStr;
+		}
+		return null;
+	}
+
+
+	/* ---------------------------------------------------------------------- */
+
+	/* Configure the test logger try to use FireBug */
+	var log, error;
+	if (window["console"] && typeof console.log == "function") {
+		log = function() {
+			if (xn.test.enableTestDebug) {
+				console.log.apply(console, arguments);
+			}
+		};
+		error = function() {
+			if (xn.test.enableTestDebug) {
+				console.error.apply(console, arguments);
+			}
+		};
+	} else {
+		log = function() {};
+	}
+
+	/* Set up something to report to */
+
+	var initialized = false;
+	var container;
+	var progressBarContainer, progressBar, overallSummaryText;
+	var currentTest = null;
+	var suites = [];
+	var totalTestCount = 0;
+	var currentTestIndex = 0;
+	var testFailed = false;
+	var testsPassedCount = 0;
+	var startTime;
+	
+	var log4javascriptEnabled = false;
+	
+	var nextSuiteIndex = 0;
+	
+	function runNextSuite() {
+		if (nextSuiteIndex < suites.length) {
+			suites[nextSuiteIndex++].run();
+		}
+	}
+	
+	var init = function() {
+		if (initialized) { return true; }
+		
+		container = document.createElement("div");
+		
+		// Create the overall progress bar
+		progressBarContainer = container.appendChild(document.createElement("div"));
+		progressBarContainer.className = "xn_test_progressbar_container xn_test_overallprogressbar_container";
+		progressBar = progressBarContainer.appendChild(document.createElement("div"));
+		progressBar.className = "success";
+
+		document.body.appendChild(container);
+
+		var h1 = progressBar.appendChild(document.createElement("h1"));
+		overallSummaryText = h1.appendChild(document.createTextNode(""));
+
+		initialized = true;
+		
+		// Set up logging
+		log4javascriptEnabled = !!log4javascript && xn.test.enable_log4javascript;
+		
+		function TestLogAppender() {}
+		
+		if (log4javascriptEnabled) {
+			TestLogAppender.prototype = new log4javascript.Appender();
+			TestLogAppender.prototype.layout = new log4javascript.PatternLayout("%d{HH:mm:ss,SSS} %-5p %m");
+			TestLogAppender.prototype.append = function(loggingEvent) {
+				var formattedMessage = this.getLayout().format(loggingEvent);
+				if (this.getLayout().ignoresThrowable()) {
+					formattedMessage += loggingEvent.getThrowableStrRep();
+				}
+				currentTest.addLogMessage(formattedMessage);
+			};
+			
+			var appender = new TestLogAppender();
+			appender.setThreshold(log4javascript.Level.ALL);
+			log4javascript.getRootLogger().addAppender(appender);
+			log4javascript.getRootLogger().setLevel(log4javascript.Level.ALL);
+		}
+
+		startTime = new Date();
+
+		// First, build each suite
+		for (var i = 0; i < suites.length; i++) {
+			suites[i].build();
+			totalTestCount += suites[i].tests.length;
+		}
+		
+		// Now run each suite
+		runNextSuite();
+	};
+	
+	function updateProgressBar() {
+		progressBar.style.width = "" + parseInt(100 * (currentTestIndex) / totalTestCount) + "%";
+		var s = (totalTestCount === 1) ? "" : "s";
+		var timeTaken = new Date().getTime() - startTime.getTime();
+		overallSummaryText.nodeValue = "" + testsPassedCount + " of " + totalTestCount + " test" + s + " passed in " + timeTaken + "ms";
+	}
+
+	addEventListener(window, "load", init);
+
+	/* ---------------------------------------------------------------------- */
+
+	/* Test Suite */
+	var Suite = function(name, callback, hideSuccessful) {
+		this.name = name;
+		this.callback = callback;
+		this.hideSuccessful = hideSuccessful;
+		this.tests = [];
+		this.log = log;
+		this.error = error;
+		this.expanded = true;
+		suites.push(this);
+	}
+
+	Suite.prototype.test = function(name, callback, setUp, tearDown) {
+		this.log("adding a test named " + name)
+		var t = new Test(name, callback, this, setUp, tearDown);
+		this.tests.push(t);
+	};
+
+	Suite.prototype.build = function() {
+		// Build the elements used by the suite
+		var suite = this;
+		this.testFailed = false;
+		this.container = document.createElement("div");
+		this.container.className = "xn_test_suite_container";
+
+		var heading = document.createElement("h2");
+		this.expander = document.createElement("span");
+		this.expander.className = "xn_test_expander";
+		this.expander.onclick = function() {
+			if (suite.expanded) {
+				suite.collapse();
+			} else {
+				suite.expand();
+			}
+		};
+		heading.appendChild(this.expander);
+		
+		this.headingTextNode = document.createTextNode(this.name);
+		heading.appendChild(this.headingTextNode);
+		this.container.appendChild(heading);
+
+		this.reportContainer = document.createElement("dl");
+		this.container.appendChild(this.reportContainer);
+
+		this.progressBarContainer = document.createElement("div");
+		this.progressBarContainer.className = "xn_test_progressbar_container";
+		this.progressBar = document.createElement("div");
+		this.progressBar.className = "success";
+		this.progressBar.innerHTML = "&nbsp;";
+		this.progressBarContainer.appendChild(this.progressBar);
+		this.reportContainer.appendChild(this.progressBarContainer);
+
+		this.expand();
+
+		container.appendChild(this.container);
+
+		// invoke callback to build the tests
+		this.callback.apply(this, [this]);
+	};
+
+	Suite.prototype.run = function() {
+		this.log("running suite '%s'", this.name)
+		this.startTime = new Date();
+
+		// now run the first test
+		this._currentIndex = 0;
+		this.runNextTest();
+	};
+
+	Suite.prototype.updateProgressBar = function() {
+		// Update progress bar
+		this.progressBar.style.width = "" + parseInt(100 * (this._currentIndex) / this.tests.length) + "%";
+		//log(this._currentIndex + ", " + this.tests.length + ", " + progressBar.style.width + ", " + progressBar.className);
+	};
+
+	Suite.prototype.expand = function() {
+		this.expander.innerHTML = "-";
+		replaceClass(this.reportContainer, "xn_test_expanded", "xn_test_collapsed");
+		this.expanded = true;
+	};
+
+	Suite.prototype.collapse = function() {
+		this.expander.innerHTML = "+";
+		replaceClass(this.reportContainer, "xn_test_collapsed", "xn_test_expanded");
+		this.expanded = false;
+	};
+
+	Suite.prototype.finish = function(timeTaken) {
+		var newClass = this.testFailed ? "xn_test_suite_failure" : "xn_test_suite_success";
+		var oldClass = this.testFailed ? "xn_test_suite_success" : "xn_test_suite_failure";
+		replaceClass(this.container, newClass, oldClass);
+
+		this.headingTextNode.nodeValue += " (" + timeTaken + "ms)";
+
+		if (this.hideSuccessful && !this.testFailed) {
+			this.collapse();
+		}
+		runNextSuite();
+	};
+
+	/**
+	 * Works recursively with external state (the next index)
+	 * so that we can handle async tests differently
+	 */
+	Suite.prototype.runNextTest = function() {
+		if (this._currentIndex == this.tests.length) {
+			// finished!
+			var timeTaken = new Date().getTime() - this.startTime.getTime();
+
+			this.finish(timeTaken);
+			return;
+		}
+
+		var suite = this;
+		var t = this.tests[this._currentIndex++];
+		currentTestIndex++;
+
+		if (isFunction(suite.setUp)) {
+			suite.setUp.apply(suite, [t]);
+		}
+		if (isFunction(t.setUp)) {
+			t.setUp.apply(t, [t]);
+		}
+
+		t._run();
+		
+		function afterTest() {
+			if (isFunction(suite.tearDown)) {
+				suite.tearDown.apply(suite, [t]);
+			}
+			if (isFunction(t.tearDown)) {
+				t.tearDown.apply(t, [t]);
+			}
+			suite.log("finished test [%s]", t.name);
+			updateProgressBar();
+			suite.updateProgressBar();
+			suite.runNextTest();
+		}
+		
+		if (t.isAsync) {
+			t.whenFinished = afterTest;
+		} else {
+			setTimeout(afterTest, 1);
+		}
+	};
+
+	Suite.prototype.reportSuccess = function() {
+	};
+
+	/* ---------------------------------------------------------------------- */
+	/**
+	 * Create a new test
+	 */
+	var Test = function(name, callback, suite, setUp, tearDown) {
+		this.name = name;
+		this.callback = callback;
+		this.suite = suite;
+		this.setUp = setUp;
+		this.tearDown = tearDown;
+		this.log = log;
+		this.error = error;
+		this.assertCount = 0;
+		this.logMessages = [];
+		this.logExpanded = false;
+	};
+
+	/**
+	 * Default success reporter, please override
+	 */
+	Test.prototype.reportSuccess = function(name, timeTaken) {
+		/* default success reporting handler */
+		this.reportHeading = document.createElement("dt");
+		var text = this.name + " passed in " + timeTaken + "ms";
+		
+		this.reportHeading.appendChild(document.createTextNode(text));
+
+		this.reportHeading.className = "success";
+		var dd = document.createElement("dd");
+		dd.className = "success";
+
+		this.suite.reportContainer.appendChild(this.reportHeading);
+		this.suite.reportContainer.appendChild(dd);
+		this.createLogReport();
+	};
+
+	/**
+	 * Cause the test to immediately fail
+	 */
+	Test.prototype.reportFailure = function(name, msg, ex) {
+		this.suite.testFailed = true;
+		this.suite.progressBar.className = "failure";
+		progressBar.className = "failure";
+		this.reportHeading = document.createElement("dt");
+		this.reportHeading.className = "failure";
+		var text = document.createTextNode(this.name);
+		this.reportHeading.appendChild(text);
+
+		var dd = document.createElement("dd");
+		dd.appendChild(document.createTextNode(msg));
+		dd.className = "failure";
+
+		this.suite.reportContainer.appendChild(this.reportHeading);
+		this.suite.reportContainer.appendChild(dd);
+		if (ex && ex.stack) {
+			var stackTraceContainer = this.suite.reportContainer.appendChild(document.createElement("code"));
+			stackTraceContainer.className = "xn_test_stacktrace";
+			stackTraceContainer.innerHTML = ex.stack.replace(/\r/g, "\n").replace(/\n{1,2}/g, "<br />");
+		}
+		this.createLogReport();
+	};
+	
+	Test.prototype.createLogReport = function() {
+		if (this.logMessages.length > 0) {
+			this.reportHeading.appendChild(document.createTextNode(" ("));
+			var logToggler = this.reportHeading.appendChild(document.createElement("a"));
+			logToggler.href = "#";
+			logToggler.innerHTML = "show log";
+			var test = this;
+			
+			logToggler.onclick = function() {
+				if (test.logExpanded) {
+					test.hideLogReport();
+					this.innerHTML = "show log";
+					test.logExpanded = false;
+				} else {
+					test.showLogReport();
+					this.innerHTML = "hide log";
+					test.logExpanded = true;
+				}
+				return false;
+			};
+
+			this.reportHeading.appendChild(document.createTextNode(")"));
+			
+			// Create log report
+			this.logReport = this.suite.reportContainer.appendChild(document.createElement("pre"));
+			this.logReport.style.display = "none";
+			this.logReport.className = "xn_test_log_report";
+			var logMessageDiv;
+			for (var i = 0, len = this.logMessages.length; i < len; i++) {
+				logMessageDiv = this.logReport.appendChild(document.createElement("div"));
+				logMessageDiv.appendChild(document.createTextNode(this.logMessages[i]));
+			}
+		}
+	};
+
+	Test.prototype.showLogReport = function() {
+		this.logReport.style.display = "inline-block";
+	};
+		
+	Test.prototype.hideLogReport = function() {
+		this.logReport.style.display = "none";
+	};
+
+	Test.prototype.async = function(timeout, callback) {
+		timeout = timeout || 250;
+		var self = this;
+		var timedOutFunc = function() {
+			if (!self.completed) {
+				var message = (typeof callback === "undefined") ?
+							"Asynchronous test timed out" : callback(self);
+				self.fail(message);
+			}
+		}
+		var timer = setTimeout(function () { timedOutFunc.apply(self, []); }, timeout)
+		this.isAsync = true;
+	};
+
+	/**
+	 * Run the test
+	 */
+	Test.prototype._run = function() {
+		this.log("starting test [%s]", this.name);
+		this.startTime = new Date();
+		currentTest = this;
+		try {
+			this.callback(this);
+			if (!this.completed && !this.isAsync) {
+				this.succeed();
+			}
+		} catch (e) {
+			this.log("test [%s] threw exception [%s]", this.name, e);
+			var s = (this.assertCount === 1) ? "" : "s";
+			this.fail("Exception thrown after " + this.assertCount + " successful assertion" + s + ": " + getExceptionStringRep(e), e);
+		}
+	};
+
+	/**
+	 * Cause the test to immediately succeed
+	 */
+	Test.prototype.succeed = function() {
+		if (this.completed) { return false; }
+		// this.log("test [%s] succeeded", this.name);
+		this.completed = true;
+		var timeTaken = new Date().getTime() - this.startTime.getTime();
+		testsPassedCount++;
+		this.reportSuccess(this.name, timeTaken);
+		if (this.whenFinished) {
+			this.whenFinished();
+		}
+	};
+
+	Test.prototype.fail = function(msg, ex)	{
+		if (typeof msg != "string") {
+			msg = getExceptionStringRep(msg);
+		}
+		if (this.completed) { return false; }
+		this.completed = true;
+		// this.log("test [%s] failed", this.name);
+		this.reportFailure(this.name, msg, ex);
+		if (this.whenFinished) {
+			this.whenFinished();
+		}
+	};
+	
+	Test.prototype.addLogMessage = function(logMessage) {
+		this.logMessages.push(logMessage);
+	};
+
+	/* assertions */
+	var displayStringForValue = function(obj) {
+		if (obj === null) {
+			return "null";
+		} else if (typeof obj === "undefined") {
+			return "undefined";
+		}
+		return obj.toString();
+	};
+
+	var assert = function(args, expectedArgsCount, testFunction, defaultComment) {
+		this.assertCount++;
+		var comment = defaultComment;
+		var i;
+		var success;
+		var values = [];
+		if (args.length == expectedArgsCount) {
+			for (i = 0; i < args.length; i++) {
+				values[i] = args[i];
+			}
+		} else if (args.length == expectedArgsCount + 1) {
+			comment = args[0];
+			for (i = 1; i < args.length; i++) {
+				values[i - 1] = args[i];
+			}
+		} else {
+			throw new Error("Invalid number of arguments passed to assert function");
+		}
+		success = testFunction(values);
+		if (!success) {
+			var regex = /\{([0-9]+)\}/;
+			while (regex.test(comment)) {
+				comment = comment.replace(regex, displayStringForValue(values[parseInt(RegExp.$1)]));
+			}
+			this.fail("Test failed on assertion " + this.assertCount + ": " + comment);
+		}
+	};
+
+	var testNull = function(values) {
+		return (values[0] === null);
+	};
+
+	Test.prototype.assertNull = function() {
+		assert.apply(this, [arguments, 1, testNull, "Expected to be null but was {0}"]);
+	}
+
+	var testNotNull = function(values) {
+		return (values[0] !== null);
+	};
+
+	Test.prototype.assertNotNull = function() {
+		assert.apply(this, [arguments, 1, testNotNull, "Expected not to be null but was {0}"]);
+	}
+
+	var testBoolean = function(values) {
+		return (Boolean(values[0]));
+	};
+
+	Test.prototype.assert = function() {
+		assert.apply(this, [arguments, 1, testBoolean, "Expected not to be equivalent to false"]);
+	};
+
+	var testTrue = function(values) {
+		return (values[0] === true);
+	};
+
+	Test.prototype.assertTrue = function() {
+		assert.apply(this, [arguments, 1, testTrue, "Expected to be true but was {0}"]);
+	};
+
+	Test.prototype.assert = function() {
+		assert.apply(this, [arguments, 1, testTrue, "Expected to be true but was {0}"]);
+	};
+
+	var testFalse = function(values) {
+		return (values[0] === false);
+	};
+
+	Test.prototype.assertFalse = function() {
+		assert.apply(this, [arguments, 1, testFalse, "Expected to be false but was {0}"]);
+	}
+
+	var testEquivalent = function(values) {
+		return (values[0] === values[1]);
+	};
+
+	Test.prototype.assertEquivalent = function() {
+		assert.apply(this, [arguments, 2, testEquivalent, "Expected to be equal but values were {0} and {1}"]);
+	}
+
+	var testNotEquivalent = function(values) {
+		return (values[0] !== values[1]);
+	};
+
+	Test.prototype.assertNotEquivalent = function() {
+		assert.apply(this, [arguments, 2, testNotEquivalent, "Expected to be not equal but values were {0} and {1}"]);
+	}
+
+	var testEquals = function(values) {
+		return (values[0] == values[1]);
+	};
+
+	Test.prototype.assertEquals = function() {
+		assert.apply(this, [arguments, 2, testEquals, "Expected to be equal but values were {0} and {1}"]);
+	}
+
+	var testNotEquals = function(values) {
+		return (values[0] != values[1]);
+	};
+
+	Test.prototype.assertNotEquals = function() {
+		assert.apply(this, [arguments, 2, testNotEquals, "Expected to be not equal but values were {0} and {1}"]);
+	}
+
+	var testRegexMatches = function(values) {
+		return (values[0].test(values[1]));
+	};
+
+	Test.prototype.assertRegexMatches = function() {
+		assert.apply(this, [arguments, 2, testRegexMatches, "Expected regex {0} to match value {1} but it didn't"]);
+	}
+
+	Test.prototype.assertError = function(f, errorType) {
+		try {
+			f();
+			this.fail("Expected error to be thrown");
+		} catch (e) {
+			if (errorType && (!(e instanceof errorType))) {
+				this.fail("Expected error of type " + errorType + " to be thrown but error thrown was " + e);
+			}
+		}
+	};
+
+	/**
+	 * Execute a synchronous test
+	 */
+	xn.test = function(name, callback) {
+		xn.test.suite("Anonymous", function(s) {
+			s.test(name, callback);
+		});
+	}
+
+	/**
+	 * Create a test suite with a given name
+	 */
+	xn.test.suite = function(name, callback, hideSuccessful) {
+		var s = new Suite(name, callback, hideSuccessful);
+	}
+})();
\ No newline at end of file
