diff --git a/.badaprj b/.badaprj
index 420dca2..cd38639 100755
--- a/.badaprj
+++ b/.badaprj
@@ -8,12 +8,12 @@
     <properties>
         <data0 key="PT CmdArgs Target-Release" value=""/>
         <data1 key="PT CertFile Simulator-Debug" value="${project_loc}\.Simulator-Debug\cert.cer"/>
-        <data2 key="PT Output Simulator-Debug" value="${project_loc}\.Simulator-Debug"/>
-        <data3 key="PT CertFile Target-Release" value="${project_loc}\.Target-Release\cert.cer"/>
+        <data2 key="PT CertFile Target-Release" value="${project_loc}\.Target-Release\cert.cer"/>
+        <data3 key="PT Output Simulator-Debug" value="${project_loc}\.Simulator-Debug"/>
         <data4 key="PT CertFile Target-Debug" value="${project_loc}\.Target-Debug\cert.cer"/>
         <data5 key="PT CmdArgs Target-Debug" value=""/>
-        <data6 key="PT CmdArgs Simulator-Debug" value=""/>
-        <data7 key="PT Output Target-Release" value="${project_loc}\.Target-Release"/>
+        <data6 key="PT Output Target-Release" value="${project_loc}\.Target-Release"/>
+        <data7 key="PT CmdArgs Simulator-Debug" value=""/>
         <data8 key="PT Output Target-Debug" value="${project_loc}\.Target-Debug"/>
     </properties>
 </bada>
diff --git a/.cproject b/.cproject
index c3a438d..676f543 100755
--- a/.cproject
+++ b/.cproject
@@ -22,11 +22,11 @@
 </extensions>
 </storageModule>
 <storageModule moduleId="cdtBuildSystem" version="4.0.0">
-<configuration artifactExtension="exe" artifactName="PhoneGap" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.osp.gnu.arm.exe.simul.1923029560" name="Simulator-Debug" parent="cdt.managedbuild.config.osp.gnu.arm.exe.simul">
+<configuration artifactExtension="exe" artifactName="Cordova" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.sharedLib" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.debug,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.sharedLib" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.osp.gnu.arm.exe.simul.1923029560" name="Simulator-Debug" parent="cdt.managedbuild.config.osp.gnu.arm.exe.simul">
 <folderInfo id="cdt.managedbuild.config.osp.gnu.arm.exe.simul.1923029560." name="/" resourcePath="">
 <toolChain id="cdt.managedbuild.toolchain.osp.gnu.arm.exe.simul.1456287273" name="bada GCC ToolChain" superClass="cdt.managedbuild.toolchain.osp.gnu.arm.exe.simul">
 <targetPlatform archList="all" binaryParser="org.eclipse.cdt.core.Cygwin_PE;org.eclipse.cdt.core.GNU_ELF;org.eclipse.cdt.core.ELF" id="cdt.managedbuild.target.osp.gnu.simul.platform.exe.simul.65186410" name="Debug Platform" osList="osp" superClass="cdt.managedbuild.target.osp.gnu.simul.platform.exe.simul"/>
-<builder buildPath="${workspace_loc:/PhoneGap/.Simulator-Debug}" command="cs-make" id="cdt.managedbuild.target.osp.gnu.simul.builder.exe.simul.1214681379" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="bada Builder" superClass="cdt.managedbuild.target.osp.gnu.simul.builder.exe.simul"/>
+<builder autoBuildTarget="all" buildPath="${workspace_loc:/Cordova/.Simulator-Debug}" cleanBuildTarget="clean" enableAutoBuild="false" enableCleanBuild="true" enabledIncrementalBuild="true" id="cdt.managedbuild.target.osp.gnu.simul.builder.exe.simul.1214681379" incrementalBuildTarget="all" keepEnvironmentInBuildfile="false" managedBuildOn="true" name="bada Builder" parallelizationNumber="1" superClass="cdt.managedbuild.target.osp.gnu.simul.builder.exe.simul"/>
 <tool id="cdt.managedbuild.tool.osp.gnu.arm.archiver.base.1279540785" name="bada Archiver" superClass="cdt.managedbuild.tool.osp.gnu.arm.archiver.base"/>
 <tool id="cdt.managedbuild.tool.osp.gnu.simul.cpp.compiler.exe.simul.1604845818" name="bada C++ Compiler" superClass="cdt.managedbuild.tool.osp.gnu.simul.cpp.compiler.exe.simul">
 <inputType id="cdt.managedbuild.tool.osp.gnu.cpp.compiler.input.1633260748" superClass="cdt.managedbuild.tool.osp.gnu.cpp.compiler.input"/>
diff --git a/.project b/.project
index 98aa230..425a19b 100755
--- a/.project
+++ b/.project
@@ -31,7 +31,7 @@
 				</dictionary>
 				<dictionary>
 					<key>org.eclipse.cdt.make.core.buildLocation</key>
-					<value>${workspace_loc:/PhoneGap/.Simulator-Debug}</value>
+					<value>${workspace_loc:/Cordova/.Simulator-Debug}</value>
 				</dictionary>
 				<dictionary>
 					<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
diff --git a/Res/mobile-spec/LICENSE b/Res/mobile-spec/LICENSE
deleted file mode 100644
index c56b998..0000000
--- a/Res/mobile-spec/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-The MIT License
-
-Copyright (c) 2009 Rob Ellis, Brock Whitten, Brian LeRoux
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
diff --git a/Res/mobile-spec/README.md b/Res/mobile-spec/README.md
deleted file mode 100644
index 96b6d5d..0000000
--- a/Res/mobile-spec/README.md
+++ /dev/null
@@ -1,37 +0,0 @@
-## Mobile Spec Suite ##
-
-These specs are designed to run inside the mobile device that implements it - _it will fail in the DESKTOP browser_.
-
-These set of tests is designed to be used with PhoneGap. You should initialize a fresh PhoneGap repository (git clone 
-git://github.com/phonegap/phonegap.git) and then toss these files into the www or assets folder, replacing the
-contents. Make sure you include phonegap.js - each platform directory in the PhoneGap repository has a build or make
-file, which will create a phonegap.js file for you (and in most cases copy it into the www or assets folder).
-
-The goal is to test mobile device functionality inside a mobile browser.
-Where possible, the PhoneGap API lines up with HTML 5 spec. Maybe down
-the road we could use this spec for parts of HTML 5, too :)
-
-
-LICENSE
----
-
-_Copyright (c) 2009 Rob Ellis, Brian LeRoux, Brock Whitten, Nitobi Software_
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be included
-in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/Res/mobile-spec/index.html b/Res/mobile-spec/index.html
deleted file mode 100755
index 166624f..0000000
--- a/Res/mobile-spec/index.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <head>
-    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
-    <meta name="viewport" content="width=device-width, height=device-height, user-scalable=yes, initial-scale=1.0;" />
-
-    <title>PhoneGap API Spec</title>
-
-    <!-- Load QUnit -->
-    <link rel="stylesheet" type="text/css" href="qunit.css" />
-    <script type="text/javascript" src="qunit.js"></script>
-
-    <!-- Load Test Runner -->
-    <script type="text/javascript" src="test-runner.js"></script>
-    
-    <!-- Source -->
-    <script type="text/javascript" src="../phonegap/phonegap.js"></script>
-    
-    <!-- Tests -->
-    <script type="text/javascript" src="tests/accelerometer.tests.js"></script>
-    <script type="text/javascript" src="tests/contacts.tests.js"></script>
-    <script type="text/javascript" src="tests/device.tests.js"></script>
-    <script type="text/javascript" src="tests/geolocation.tests.js"></script>
-    <script type="text/javascript" src="tests/network.tests.js"></script>
-    <script type="text/javascript" src="tests/notification.tests.js"></script>
-    <script type="text/javascript" src="tests/camera.tests.js"></script>
-  </head>
-    <body>
-       <ul id="debuglist">Debug Output</ul>
-        <!--<ul id="debuglist">Debug Output</ul>-->
-        <h1 id="qunit-header">PhoneGap API Spec</h1>
-        <h2 id="qunit-banner"></h2>
-        <h2 id="qunit-userAgent"></h2>
-        <ol id="qunit-tests"></ol>
-        <div id="qunit-fixture">
-            <!-- Populated by tests -->
-        </div>
-    </body>
-</html>
diff --git a/Res/mobile-spec/qunit.css b/Res/mobile-spec/qunit.css
deleted file mode 100644
index 78a7d7e..0000000
--- a/Res/mobile-spec/qunit.css
+++ /dev/null
@@ -1,215 +0,0 @@
-/** Font Family and Sizes */
-
-#qunit-tests, #qunit-header, #qunit-banner, #qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult {
-	font-family: "Helvetica Neue Light", "HelveticaNeue-Light", "Helvetica Neue", Calibri, Helvetica, Arial;
-}
-
-#qunit-testrunner-toolbar, #qunit-userAgent, #qunit-testresult, #qunit-tests li { font-size: small; }
-#qunit-tests { font-size: smaller; }
-
-
-/** Resets */
-
-#qunit-tests, #qunit-tests ol, #qunit-header, #qunit-banner, #qunit-userAgent, #qunit-testresult {
-	margin: 0;
-	padding: 0;
-}
-
-
-/** Header */
-
-#qunit-header {
-	padding: 0.5em 0 0.5em 1em;
-
-	color: #8699a4;
-	background-color: #0d3349;
-
-	font-size: 1.5em;
-	line-height: 1em;
-	font-weight: normal;
-	
-	border-radius: 15px 15px 0 0;
-	-moz-border-radius: 15px 15px 0 0;
-	-webkit-border-top-right-radius: 15px;
-	-webkit-border-top-left-radius: 15px;
-}
-
-#qunit-header a {
-	text-decoration: none;
-	color: #c2ccd1;
-}
-
-#qunit-header a:hover,
-#qunit-header a:focus {
-	color: #fff;
-}
-
-#qunit-banner {
-	height: 5px;
-}
-
-#qunit-testrunner-toolbar {
-	padding: 0.5em 0 0.5em 2em;
-	color: #5E740B;
-	background-color: #eee;
-}
-
-#qunit-userAgent {
-	padding: 0.5em 0 0.5em 2.5em;
-	background-color: #2b81af;
-	color: #fff;
-	text-shadow: rgba(0, 0, 0, 0.5) 2px 2px 1px;
-}
-
-
-/** Tests: Pass/Fail */
-
-#qunit-tests {
-	list-style-position: inside;
-}
-
-#qunit-tests li {
-	padding: 0.4em 0.5em 0.4em 2.5em;
-	border-bottom: 1px solid #fff;
-	list-style-position: inside;
-}
-
-#qunit-tests.hidepass li.pass, #qunit-tests.hidepass li.running  {
-	display: none;
-}
-
-#qunit-tests li strong {
-	cursor: pointer;
-}
-
-#qunit-tests li a {
-	padding: 0.5em;
-	color: #c2ccd1;
-	text-decoration: none;
-}
-#qunit-tests li a:hover,
-#qunit-tests li a:focus {
-	color: #000;
-}
-
-#qunit-tests ol {
-	margin-top: 0.5em;
-	padding: 0.5em;
-	
-	background-color: #fff;
-	
-	border-radius: 15px;
-	-moz-border-radius: 15px;
-	-webkit-border-radius: 15px;
-	
-	box-shadow: inset 0px 2px 13px #999;
-	-moz-box-shadow: inset 0px 2px 13px #999;
-	-webkit-box-shadow: inset 0px 2px 13px #999;
-}
-
-#qunit-tests table {
-	border-collapse: collapse;
-	margin-top: .2em;
-}
-
-#qunit-tests th {
-	text-align: right;
-	vertical-align: top;
-	padding: 0 .5em 0 0;
-}
-
-#qunit-tests td {
-	vertical-align: top;
-}
-
-#qunit-tests pre {
-	margin: 0;
-	white-space: pre-wrap;
-	word-wrap: break-word;
-}
-
-#qunit-tests del {
-	background-color: #e0f2be;
-	color: #374e0c;
-	text-decoration: none;
-}
-
-#qunit-tests ins {
-	background-color: #ffcaca;
-	color: #500;
-	text-decoration: none;
-}
-
-/*** Test Counts */
-
-#qunit-tests b.counts                       { color: black; }
-#qunit-tests b.passed                       { color: #5E740B; }
-#qunit-tests b.failed                       { color: #710909; }
-
-#qunit-tests li li {
-	margin: 0.5em;
-	padding: 0.4em 0.5em 0.4em 0.5em;
-	background-color: #fff;
-	border-bottom: none;
-	list-style-position: inside;
-}
-
-/*** Passing Styles */
-
-#qunit-tests li li.pass {
-	color: #5E740B;
-	background-color: #fff;
-	border-left: 26px solid #C6E746;
-}
-
-#qunit-tests .pass                          { color: #528CE0; background-color: #D2E0E6; }
-#qunit-tests .pass .test-name               { color: #366097; }
- 
-#qunit-tests .pass .test-actual,
-#qunit-tests .pass .test-expected           { color: #999999; }
-
-#qunit-banner.qunit-pass                    { background-color: #C6E746; }
-
-/*** Failing Styles */
-
-#qunit-tests li li.fail {
-	color: #710909;
-	background-color: #fff;
-	border-left: 26px solid #EE5757;
-}
-
-#qunit-tests > li:last-child {
-	border-radius: 0 0 15px 15px;
-	-moz-border-radius: 0 0 15px 15px;
-	-webkit-border-bottom-right-radius: 15px;
-	-webkit-border-bottom-left-radius: 15px;
-}
-
-#qunit-tests .fail                          { color: #000000; background-color: #EE5757; }
-#qunit-tests .fail .test-name,
-#qunit-tests .fail .module-name             { color: #000000; }
-
-#qunit-tests .fail .test-actual             { color: #EE5757; }
-#qunit-tests .fail .test-expected           { color: green;   }
-
-#qunit-banner.qunit-fail                    { background-color: #EE5757; }
-
-
-/** Result */
-
-#qunit-testresult {
-	padding: 0.5em 0.5em 0.5em 2.5em;
-
-	color: #2b81af;
-	background-color: #D2E0E6;
-
-	border-bottom: 1px solid white;
-}
-
-/** Fixture */
-
-#qunit-fixture {
-	position: absolute;
-	top: -10000px;
-	left: -10000px;
-}
diff --git a/Res/mobile-spec/qunit.js b/Res/mobile-spec/qunit.js
deleted file mode 100644
index 358be2d..0000000
--- a/Res/mobile-spec/qunit.js
+++ /dev/null
@@ -1,1434 +0,0 @@
-/*
- * QUnit - A JavaScript Unit Testing Framework
- * 
- * http://docs.jquery.com/QUnit
- *
- * Copyright (c) 2011 John Resig, Jörn Zaefferer
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * or GPL (GPL-LICENSE.txt) licenses.
- */
-
-(function(window) {
-
-var defined = {
-	setTimeout: typeof window.setTimeout !== "undefined",
-	sessionStorage: (function() {
-		try {
-			return !!sessionStorage.getItem;
-		} catch(e){
-			return false;
-		}
-  })()
-};
-
-var testId = 0;
-
-var Test = function(name, testName, expected, testEnvironmentArg, async, callback) {
-	this.name = name;
-	this.testName = testName;
-	this.expected = expected;
-	this.testEnvironmentArg = testEnvironmentArg;
-	this.async = async;
-	this.callback = callback;
-	this.assertions = [];
-};
-Test.prototype = {
-	init: function() {
-		var tests = id("qunit-tests");
-		if (tests) {
-			var b = document.createElement("strong");
-				b.innerHTML = "Running " + this.name;
-			var li = document.createElement("li");
-				li.appendChild( b );
-				li.className = "running";
-				li.id = this.id = "test-output" + testId++;
-			tests.appendChild( li );
-		}
-	},
-	setup: function() {
-		if (this.module != config.previousModule) {
-			if ( config.previousModule ) {
-				QUnit.moduleDone( {
-					name: config.previousModule,
-					failed: config.moduleStats.bad,
-					passed: config.moduleStats.all - config.moduleStats.bad,
-					total: config.moduleStats.all
-				} );
-			}
-			config.previousModule = this.module;
-			config.moduleStats = { all: 0, bad: 0 };
-			QUnit.moduleStart( {
-				name: this.module
-			} );
-		}
-
-		config.current = this;
-		this.testEnvironment = extend({
-			setup: function() {},
-			teardown: function() {}
-		}, this.moduleTestEnvironment);
-		if (this.testEnvironmentArg) {
-			extend(this.testEnvironment, this.testEnvironmentArg);
-		}
-
-		QUnit.testStart( {
-			name: this.testName
-		} );
-
-		// allow utility functions to access the current test environment
-		// TODO why??
-		QUnit.current_testEnvironment = this.testEnvironment;
-		
-		try {
-			if ( !config.pollution ) {
-				saveGlobal();
-			}
-
-			this.testEnvironment.setup.call(this.testEnvironment);
-		} catch(e) {
-			QUnit.ok( false, "Setup failed on " + this.testName + ": " + e.message );
-		}
-	},
-	run: function() {
-		if ( this.async ) {
-			QUnit.stop();
-		}
-
-		if ( config.notrycatch ) {
-			this.callback.call(this.testEnvironment);
-			return;
-		}
-		try {
-			this.callback.call(this.testEnvironment);
-		} catch(e) {
-			fail("Test " + this.testName + " died, exception and test follows", e, this.callback);
-			QUnit.ok( false, "Died on test #" + (this.assertions.length + 1) + ": " + e.message + " - " + QUnit.jsDump.parse(e) );
-			// else next test will carry the responsibility
-			saveGlobal();
-
-			// Restart the tests if they're blocking
-			if ( config.blocking ) {
-				start();
-			}
-		}
-	},
-	teardown: function() {
-		try {
-			checkPollution();
-			this.testEnvironment.teardown.call(this.testEnvironment);
-		} catch(e) {
-			QUnit.ok( false, "Teardown failed on " + this.testName + ": " + e.message );
-		}
-	},
-	finish: function() {
-		if ( this.expected && this.expected != this.assertions.length ) {
-			QUnit.ok( false, "Expected " + this.expected + " assertions, but " + this.assertions.length + " were run" );
-		}
-		
-		var good = 0, bad = 0,
-			tests = id("qunit-tests");
-
-		config.stats.all += this.assertions.length;
-		config.moduleStats.all += this.assertions.length;
-
-		if ( tests ) {
-			var ol  = document.createElement("ol");
-
-			for ( var i = 0; i < this.assertions.length; i++ ) {
-				var assertion = this.assertions[i];
-
-				var li = document.createElement("li");
-				li.className = assertion.result ? "pass" : "fail";
-				li.innerHTML = assertion.message || (assertion.result ? "okay" : "failed");
-				ol.appendChild( li );
-
-				if ( assertion.result ) {
-					good++;
-				} else {
-					bad++;
-					config.stats.bad++;
-					config.moduleStats.bad++;
-				}
-			}
-
-			// store result when possible
-			QUnit.config.reorder && defined.sessionStorage && sessionStorage.setItem("qunit-" + this.testName, bad);
-
-			if (bad == 0) {
-				ol.style.display = "none";
-			}
-
-			var b = document.createElement("strong");
-			b.innerHTML = this.name + " <b class='counts'>(<b class='failed'>" + bad + "</b>, <b class='passed'>" + good + "</b>, " + this.assertions.length + ")</b>";
-			
-			var a = document.createElement("a");
-			a.innerHTML = "Rerun";
-			a.href = QUnit.url({ filter: getText([b]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") });
-			
-			addEvent(b, "click", function() {
-				var next = b.nextSibling.nextSibling,
-					display = next.style.display;
-				next.style.display = display === "none" ? "block" : "none";
-			});
-			
-			addEvent(b, "dblclick", function(e) {
-				var target = e && e.target ? e.target : window.event.srcElement;
-				if ( target.nodeName.toLowerCase() == "span" || target.nodeName.toLowerCase() == "b" ) {
-					target = target.parentNode;
-				}
-				if ( window.location && target.nodeName.toLowerCase() === "strong" ) {
-					window.location = QUnit.url({ filter: getText([target]).replace(/\([^)]+\)$/, "").replace(/(^\s*|\s*$)/g, "") });
-				}
-			});
-
-			var li = id(this.id);
-			li.className = bad ? "fail" : "pass";
-			li.removeChild( li.firstChild );
-			li.appendChild( b );
-			li.appendChild( a );
-			li.appendChild( ol );
-
-		} else {
-			for ( var i = 0; i < this.assertions.length; i++ ) {
-				if ( !this.assertions[i].result ) {
-					bad++;
-					config.stats.bad++;
-					config.moduleStats.bad++;
-				}
-			}
-		}
-
-		try {
-			QUnit.reset();
-		} catch(e) {
-			fail("reset() failed, following Test " + this.testName + ", exception and reset fn follows", e, QUnit.reset);
-		}
-
-		QUnit.testDone( {
-			name: this.testName,
-			failed: bad,
-			passed: this.assertions.length - bad,
-			total: this.assertions.length
-		} );
-	},
-	
-	queue: function() {
-		var test = this;
-		synchronize(function() {
-			test.init();
-		});
-		function run() {
-			// each of these can by async
-			synchronize(function() {
-				test.setup();
-			});
-			synchronize(function() {
-				test.run();
-			});
-			synchronize(function() {
-				test.teardown();
-			});
-			synchronize(function() {
-				test.finish();
-			});
-		}
-		// defer when previous test run passed, if storage is available
-		var bad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-" + this.testName);
-		if (bad) {
-			run();
-		} else {
-			synchronize(run);
-		};
-	}
-	
-};
-
-var QUnit = {
-
-	// call on start of module test to prepend name to all tests
-	module: function(name, testEnvironment) {
-		config.currentModule = name;
-		config.currentModuleTestEnviroment = testEnvironment;
-	},
-
-	asyncTest: function(testName, expected, callback) {
-		if ( arguments.length === 2 ) {
-			callback = expected;
-			expected = 0;
-		}
-
-		QUnit.test(testName, expected, callback, true);
-	},
-	
-	test: function(testName, expected, callback, async) {
-		var name = '<span class="test-name">' + testName + '</span>', testEnvironmentArg;
-
-		if ( arguments.length === 2 ) {
-			callback = expected;
-			expected = null;
-		}
-		// is 2nd argument a testEnvironment?
-		if ( expected && typeof expected === 'object') {
-			testEnvironmentArg =  expected;
-			expected = null;
-		}
-
-		if ( config.currentModule ) {
-			name = '<span class="module-name">' + config.currentModule + "</span>: " + name;
-		}
-
-		if ( !validTest(config.currentModule + ": " + testName) ) {
-			return;
-		}
-		
-		var test = new Test(name, testName, expected, testEnvironmentArg, async, callback);
-		test.module = config.currentModule;
-		test.moduleTestEnvironment = config.currentModuleTestEnviroment;
-		test.queue();
-	},
-	
-	/**
-	 * Specify the number of expected assertions to gurantee that failed test (no assertions are run at all) don't slip through.
-	 */
-	expect: function(asserts) {
-		config.current.expected = asserts;
-	},
-
-	/**
-	 * Asserts true.
-	 * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
-	 */
-	ok: function(a, msg) {
-		a = !!a;
-		var details = {
-			result: a,
-			message: msg
-		};
-		msg = escapeHtml(msg);
-		QUnit.log(details);
-		config.current.assertions.push({
-			result: a,
-			message: msg
-		});
-	},
-
-	/**
-	 * Checks that the first two arguments are equal, with an optional message.
-	 * Prints out both actual and expected values.
-	 *
-	 * Prefered to ok( actual == expected, message )
-	 *
-	 * @example equal( format("Received {0} bytes.", 2), "Received 2 bytes." );
-	 *
-	 * @param Object actual
-	 * @param Object expected
-	 * @param String message (optional)
-	 */
-	equal: function(actual, expected, message) {
-		QUnit.push(expected == actual, actual, expected, message);
-	},
-
-	notEqual: function(actual, expected, message) {
-		QUnit.push(expected != actual, actual, expected, message);
-	},
-	
-	deepEqual: function(actual, expected, message) {
-		QUnit.push(QUnit.equiv(actual, expected), actual, expected, message);
-	},
-
-	notDeepEqual: function(actual, expected, message) {
-		QUnit.push(!QUnit.equiv(actual, expected), actual, expected, message);
-	},
-
-	strictEqual: function(actual, expected, message) {
-		QUnit.push(expected === actual, actual, expected, message);
-	},
-
-	notStrictEqual: function(actual, expected, message) {
-		QUnit.push(expected !== actual, actual, expected, message);
-	},
-
-	raises: function(block, expected, message) {
-		var actual, ok = false;
-	
-		if (typeof expected === 'string') {
-			message = expected;
-			expected = null;
-		}
-	
-		try {
-			block();
-		} catch (e) {
-			actual = e;
-		}
-	
-		if (actual) {
-			// we don't want to validate thrown error
-			if (!expected) {
-				ok = true;
-			// expected is a regexp	
-			} else if (QUnit.objectType(expected) === "regexp") {
-				ok = expected.test(actual);
-			// expected is a constructor	
-			} else if (actual instanceof expected) {
-				ok = true;
-			// expected is a validation function which returns true is validation passed	
-			} else if (expected.call({}, actual) === true) {
-				ok = true;
-			}
-		}
-			
-		QUnit.ok(ok, message);
-	},
-
-	start: function() {
-		config.semaphore--;
-		if (config.semaphore > 0) {
-			// don't start until equal number of stop-calls
-			return;
-		}
-		if (config.semaphore < 0) {
-			// ignore if start is called more often then stop
-			config.semaphore = 0;
-		}
-		// A slight delay, to avoid any current callbacks
-		if ( defined.setTimeout ) {
-			window.setTimeout(function() {
-				if ( config.timeout ) {
-					clearTimeout(config.timeout);
-				}
-
-				config.blocking = false;
-				process();
-			}, 13);
-		} else {
-			config.blocking = false;
-			process();
-		}
-	},
-	
-	stop: function(timeout) {
-		config.semaphore++;
-		config.blocking = true;
-
-		if ( timeout && defined.setTimeout ) {
-			clearTimeout(config.timeout);
-			config.timeout = window.setTimeout(function() {
-				QUnit.ok( false, "Test timed out" );
-				QUnit.start();
-			}, timeout);
-		}
-	}
-};
-
-// Backwards compatibility, deprecated
-QUnit.equals = QUnit.equal;
-QUnit.same = QUnit.deepEqual;
-
-// Maintain internal state
-var config = {
-	// The queue of tests to run
-	queue: [],
-
-	// block until document ready
-	blocking: true,
-	
-	// by default, run previously failed tests first
-	// very useful in combination with "Hide passed tests" checked
-	reorder: true,
-
-	noglobals: false,
-	notrycatch: false
-};
-
-// Load paramaters
-(function() {
-	var location = window.location || { search: "", protocol: "file:" },
-		params = location.search.slice( 1 ).split( "&" ),
-		length = params.length,
-		urlParams = {},
-		current;
-
-	if ( params[ 0 ] ) {
-		for ( var i = 0; i < length; i++ ) {
-			current = params[ i ].split( "=" );
-			current[ 0 ] = decodeURIComponent( current[ 0 ] );
-			// allow just a key to turn on a flag, e.g., test.html?noglobals
-			current[ 1 ] = current[ 1 ] ? decodeURIComponent( current[ 1 ] ) : true;
-			urlParams[ current[ 0 ] ] = current[ 1 ];
-			if ( current[ 0 ] in config ) {
-				config[ current[ 0 ] ] = current[ 1 ];
-			}
-		}
-	}
-
-	QUnit.urlParams = urlParams;
-	config.filter = urlParams.filter;
-
-	// Figure out if we're running the tests from a server or not
-	QUnit.isLocal = !!(location.protocol === 'file:');
-})();
-
-// Expose the API as global variables, unless an 'exports'
-// object exists, in that case we assume we're in CommonJS
-if ( typeof exports === "undefined" || typeof require === "undefined" ) {
-	extend(window, QUnit);
-	window.QUnit = QUnit;
-} else {
-	extend(exports, QUnit);
-	exports.QUnit = QUnit;
-}
-
-// define these after exposing globals to keep them in these QUnit namespace only
-extend(QUnit, {
-	config: config,
-
-	// Initialize the configuration options
-	init: function() {
-		extend(config, {
-			stats: { all: 0, bad: 0 },
-			moduleStats: { all: 0, bad: 0 },
-			started: +new Date,
-			updateRate: 1000,
-			blocking: false,
-			autostart: true,
-			autorun: false,
-			filter: "",
-			queue: [],
-			semaphore: 0
-		});
-
-		var tests = id( "qunit-tests" ),
-			banner = id( "qunit-banner" ),
-			result = id( "qunit-testresult" );
-
-		if ( tests ) {
-			tests.innerHTML = "";
-		}
-
-		if ( banner ) {
-			banner.className = "";
-		}
-
-		if ( result ) {
-			result.parentNode.removeChild( result );
-		}
-		
-		if ( tests ) {
-			result = document.createElement( "p" );
-			result.id = "qunit-testresult";
-			result.className = "result";
-			tests.parentNode.insertBefore( result, tests );
-			result.innerHTML = 'Running...<br/>&nbsp;';
-		}
-	},
-	
-	/**
-	 * Resets the test setup. Useful for tests that modify the DOM.
-	 * 
-	 * If jQuery is available, uses jQuery's html(), otherwise just innerHTML.
-	 */
-	reset: function() {
-		if ( window.jQuery ) {
-			jQuery( "#main, #qunit-fixture" ).html( config.fixture );
-		} else {
-			var main = id( 'main' ) || id( 'qunit-fixture' );
-			if ( main ) {
-				main.innerHTML = config.fixture;
-			}
-		}
-	},
-	
-	/**
-	 * Trigger an event on an element.
-	 *
-	 * @example triggerEvent( document.body, "click" );
-	 *
-	 * @param DOMElement elem
-	 * @param String type
-	 */
-	triggerEvent: function( elem, type, event ) {
-		if ( document.createEvent ) {
-			event = document.createEvent("MouseEvents");
-			event.initMouseEvent(type, true, true, elem.ownerDocument.defaultView,
-				0, 0, 0, 0, 0, false, false, false, false, 0, null);
-			elem.dispatchEvent( event );
-
-		} else if ( elem.fireEvent ) {
-			elem.fireEvent("on"+type);
-		}
-	},
-	
-	// Safe object type checking
-	is: function( type, obj ) {
-		return QUnit.objectType( obj ) == type;
-	},
-	
-	objectType: function( obj ) {
-		if (typeof obj === "undefined") {
-				return "undefined";
-
-		// consider: typeof null === object
-		}
-		if (obj === null) {
-				return "null";
-		}
-
-		var type = Object.prototype.toString.call( obj )
-			.match(/^\[object\s(.*)\]$/)[1] || '';
-
-		switch (type) {
-				case 'Number':
-						if (isNaN(obj)) {
-								return "nan";
-						} else {
-								return "number";
-						}
-				case 'String':
-				case 'Boolean':
-				case 'Array':
-				case 'Date':
-				case 'RegExp':
-				case 'Function':
-						return type.toLowerCase();
-		}
-		if (typeof obj === "object") {
-				return "object";
-		}
-		return undefined;
-	},
-	
-	push: function(result, actual, expected, message) {
-		var details = {
-			result: result,
-			message: message,
-			actual: actual,
-			expected: expected
-		};
-		
-		message = escapeHtml(message) || (result ? "okay" : "failed");
-		message = '<span class="test-message">' + message + "</span>";
-		expected = escapeHtml(QUnit.jsDump.parse(expected));
-		actual = escapeHtml(QUnit.jsDump.parse(actual));
-		var output = message + '<table><tr class="test-expected"><th>Expected: </th><td><pre>' + expected + '</pre></td></tr>';
-		if (actual != expected) {
-			output += '<tr class="test-actual"><th>Result: </th><td><pre>' + actual + '</pre></td></tr>';
-			output += '<tr class="test-diff"><th>Diff: </th><td><pre>' + QUnit.diff(expected, actual) +'</pre></td></tr>';
-		}
-		if (!result) {
-			var source = sourceFromStacktrace();
-			if (source) {
-				details.source = source;
-				output += '<tr class="test-source"><th>Source: </th><td><pre>' + source +'</pre></td></tr>';
-			}
-		}
-		output += "</table>";
-		
-		QUnit.log(details);
-		
-		config.current.assertions.push({
-			result: !!result,
-			message: output
-		});
-	},
-	
-	url: function( params ) {
-		params = extend( extend( {}, QUnit.urlParams ), params );
-		var querystring = "?",
-			key;
-		for ( key in params ) {
-			querystring += encodeURIComponent( key ) + "=" +
-				encodeURIComponent( params[ key ] ) + "&";
-		}
-		return window.location.pathname + querystring.slice( 0, -1 );
-	},
-	
-	// Logging callbacks; all receive a single argument with the listed properties
-	// run test/logs.html for any related changes
-	begin: function() {},
-	// done: { failed, passed, total, runtime }
-	done: function() {},
-	// log: { result, actual, expected, message }
-	log: function() {},
-	// testStart: { name }
-	testStart: function() {},
-	// testDone: { name, failed, passed, total }
-	testDone: function() {},
-	// moduleStart: { name }
-	moduleStart: function() {},
-	// moduleDone: { name, failed, passed, total }
-	moduleDone: function() {}
-});
-
-if ( typeof document === "undefined" || document.readyState === "complete" ) {
-	config.autorun = true;
-}
-
-addEvent(window, "load", function() {
-	QUnit.begin({});
-	
-	// Initialize the config, saving the execution queue
-	var oldconfig = extend({}, config);
-	QUnit.init();
-	extend(config, oldconfig);
-
-	config.blocking = false;
-
-	var userAgent = id("qunit-userAgent");
-	if ( userAgent ) {
-		userAgent.innerHTML = navigator.userAgent;
-	}
-	var banner = id("qunit-header");
-	if ( banner ) {
-		banner.innerHTML = '<a href="' + QUnit.url({ filter: undefined }) + '"> ' + banner.innerHTML + '</a> ' +
-			'<label><input name="noglobals" type="checkbox"' + ( config.noglobals ? ' checked="checked"' : '' ) + '>noglobals</label>' +
-			'<label><input name="notrycatch" type="checkbox"' + ( config.notrycatch ? ' checked="checked"' : '' ) + '>notrycatch</label>';
-		addEvent( banner, "change", function( event ) {
-			var params = {};
-			params[ event.target.name ] = event.target.checked ? true : undefined;
-			window.location = QUnit.url( params );
-		});
-	}
-	
-	var toolbar = id("qunit-testrunner-toolbar");
-	if ( toolbar ) {
-		var filter = document.createElement("input");
-		filter.type = "checkbox";
-		filter.id = "qunit-filter-pass";
-		addEvent( filter, "click", function() {
-			var ol = document.getElementById("qunit-tests");
-			if ( filter.checked ) {
-				ol.className = ol.className + " hidepass";
-			} else {
-				var tmp = " " + ol.className.replace( /[\n\t\r]/g, " " ) + " ";
-				ol.className = tmp.replace(/ hidepass /, " ");
-			}
-			if ( defined.sessionStorage ) {
-				sessionStorage.setItem("qunit-filter-passed-tests", filter.checked ? "true" : "");
-			}
-		});
-		if ( defined.sessionStorage && sessionStorage.getItem("qunit-filter-passed-tests") ) {
-			filter.checked = true;
-			var ol = document.getElementById("qunit-tests");
-			ol.className = ol.className + " hidepass";
-		}
-		toolbar.appendChild( filter );
-
-		var label = document.createElement("label");
-		label.setAttribute("for", "qunit-filter-pass");
-		label.innerHTML = "Hide passed tests";
-		toolbar.appendChild( label );
-	}
-
-	var main = id('main') || id('qunit-fixture');
-	if ( main ) {
-		config.fixture = main.innerHTML;
-	}
-
-	if (config.autostart) {
-		QUnit.start();
-	}
-});
-
-function done() {
-	config.autorun = true;
-
-	// Log the last module results
-	if ( config.currentModule ) {
-		QUnit.moduleDone( {
-			name: config.currentModule,
-			failed: config.moduleStats.bad,
-			passed: config.moduleStats.all - config.moduleStats.bad,
-			total: config.moduleStats.all
-		} );
-	}
-
-	var banner = id("qunit-banner"),
-		tests = id("qunit-tests"),
-		runtime = +new Date - config.started,
-		passed = config.stats.all - config.stats.bad,
-		html = [
-			'Tests completed in ',
-			runtime,
-			' milliseconds.<br/>',
-			'<span class="passed">',
-			passed,
-			'</span> tests of <span class="total">',
-			config.stats.all,
-			'</span> passed, <span class="failed">',
-			config.stats.bad,
-			'</span> failed.'
-		].join('');
-
-	if ( banner ) {
-		banner.className = (config.stats.bad ? "qunit-fail" : "qunit-pass");
-	}
-
-	if ( tests ) {	
-		id( "qunit-testresult" ).innerHTML = html;
-	}
-
-	QUnit.done( {
-		failed: config.stats.bad,
-		passed: passed, 
-		total: config.stats.all,
-		runtime: runtime
-	} );
-}
-
-function validTest( name ) {
-	var filter = config.filter,
-		run = false;
-
-	if ( !filter ) {
-		return true;
-	}
-
-	not = filter.charAt( 0 ) === "!";
-	if ( not ) {
-		filter = filter.slice( 1 );
-	}
-
-	if ( name.indexOf( filter ) !== -1 ) {
-		return !not;
-	}
-
-	if ( not ) {
-		run = true;
-	}
-
-	return run;
-}
-
-// so far supports only Firefox, Chrome and Opera (buggy)
-// could be extended in the future to use something like https://github.com/csnover/TraceKit
-function sourceFromStacktrace() {
-	try {
-		throw new Error();
-	} catch ( e ) {
-		if (e.stacktrace) {
-			// Opera
-			return e.stacktrace.split("\n")[6];
-		} else if (e.stack) {
-			// Firefox, Chrome
-			return e.stack.split("\n")[4];
-		}
-	}
-}
-
-function escapeHtml(s) {
-	if (!s) {
-		return "";
-	}
-	s = s + "";
-	return s.replace(/[\&"<>\\]/g, function(s) {
-		switch(s) {
-			case "&": return "&amp;";
-			case "\\": return "\\\\";
-			case '"': return '\"';
-			case "<": return "&lt;";
-			case ">": return "&gt;";
-			default: return s;
-		}
-	});
-}
-
-function synchronize( callback ) {
-	config.queue.push( callback );
-
-	if ( config.autorun && !config.blocking ) {
-		process();
-	}
-}
-
-function process() {
-	var start = (new Date()).getTime();
-
-	while ( config.queue.length && !config.blocking ) {
-		if ( config.updateRate <= 0 || (((new Date()).getTime() - start) < config.updateRate) ) {
-			config.queue.shift()();
-		} else {
-			window.setTimeout( process, 13 );
-			break;
-		}
-	}
-  if (!config.blocking && !config.queue.length) {
-    done();
-  }
-}
-
-function saveGlobal() {
-	config.pollution = [];
-	
-	if ( config.noglobals ) {
-		for ( var key in window ) {
-			config.pollution.push( key );
-		}
-	}
-}
-
-function checkPollution( name ) {
-	var old = config.pollution;
-	saveGlobal();
-	
-	var newGlobals = diff( old, config.pollution );
-	if ( newGlobals.length > 0 ) {
-		ok( false, "Introduced global variable(s): " + newGlobals.join(", ") );
-		config.current.expected++;
-	}
-
-	var deletedGlobals = diff( config.pollution, old );
-	if ( deletedGlobals.length > 0 ) {
-		ok( false, "Deleted global variable(s): " + deletedGlobals.join(", ") );
-		config.current.expected++;
-	}
-}
-
-// returns a new Array with the elements that are in a but not in b
-function diff( a, b ) {
-	var result = a.slice();
-	for ( var i = 0; i < result.length; i++ ) {
-		for ( var j = 0; j < b.length; j++ ) {
-			if ( result[i] === b[j] ) {
-				result.splice(i, 1);
-				i--;
-				break;
-			}
-		}
-	}
-	return result;
-}
-
-function fail(message, exception, callback) {
-	if ( typeof console !== "undefined" && console.error && console.warn ) {
-		console.error(message);
-		console.error(exception);
-		console.warn(callback.toString());
-
-	} else if ( window.opera && opera.postError ) {
-		opera.postError(message, exception, callback.toString);
-	}
-}
-
-function extend(a, b) {
-	for ( var prop in b ) {
-		if ( b[prop] === undefined ) {
-			delete a[prop];
-		} else {
-			a[prop] = b[prop];
-		}
-	}
-
-	return a;
-}
-
-function addEvent(elem, type, fn) {
-	if ( elem.addEventListener ) {
-		elem.addEventListener( type, fn, false );
-	} else if ( elem.attachEvent ) {
-		elem.attachEvent( "on" + type, fn );
-	} else {
-		fn();
-	}
-}
-
-function id(name) {
-	return !!(typeof document !== "undefined" && document && document.getElementById) &&
-		document.getElementById( name );
-}
-
-// Test for equality any JavaScript type.
-// Discussions and reference: http://philrathe.com/articles/equiv
-// Test suites: http://philrathe.com/tests/equiv
-// Author: Philippe Rathé <prathe@gmail.com>
-QUnit.equiv = function () {
-
-    var innerEquiv; // the real equiv function
-    var callers = []; // stack to decide between skip/abort functions
-    var parents = []; // stack to avoiding loops from circular referencing
-
-    // Call the o related callback with the given arguments.
-    function bindCallbacks(o, callbacks, args) {
-        var prop = QUnit.objectType(o);
-        if (prop) {
-            if (QUnit.objectType(callbacks[prop]) === "function") {
-                return callbacks[prop].apply(callbacks, args);
-            } else {
-                return callbacks[prop]; // or undefined
-            }
-        }
-    }
-    
-    var callbacks = function () {
-
-        // for string, boolean, number and null
-        function useStrictEquality(b, a) {
-            if (b instanceof a.constructor || a instanceof b.constructor) {
-                // to catch short annotaion VS 'new' annotation of a declaration
-                // e.g. var i = 1;
-                //      var j = new Number(1);
-                return a == b;
-            } else {
-                return a === b;
-            }
-        }
-
-        return {
-            "string": useStrictEquality,
-            "boolean": useStrictEquality,
-            "number": useStrictEquality,
-            "null": useStrictEquality,
-            "undefined": useStrictEquality,
-
-            "nan": function (b) {
-                return isNaN(b);
-            },
-
-            "date": function (b, a) {
-                return QUnit.objectType(b) === "date" && a.valueOf() === b.valueOf();
-            },
-
-            "regexp": function (b, a) {
-                return QUnit.objectType(b) === "regexp" &&
-                    a.source === b.source && // the regex itself
-                    a.global === b.global && // and its modifers (gmi) ...
-                    a.ignoreCase === b.ignoreCase &&
-                    a.multiline === b.multiline;
-            },
-
-            // - skip when the property is a method of an instance (OOP)
-            // - abort otherwise,
-            //   initial === would have catch identical references anyway
-            "function": function () {
-                var caller = callers[callers.length - 1];
-                return caller !== Object &&
-                        typeof caller !== "undefined";
-            },
-
-            "array": function (b, a) {
-                var i, j, loop;
-                var len;
-
-                // b could be an object literal here
-                if ( ! (QUnit.objectType(b) === "array")) {
-                    return false;
-                }   
-                
-                len = a.length;
-                if (len !== b.length) { // safe and faster
-                    return false;
-                }
-                
-                //track reference to avoid circular references
-                parents.push(a);
-                for (i = 0; i < len; i++) {
-                    loop = false;
-                    for(j=0;j<parents.length;j++){
-                        if(parents[j] === a[i]){
-                            loop = true;//dont rewalk array
-                        }
-                    }
-                    if (!loop && ! innerEquiv(a[i], b[i])) {
-                        parents.pop();
-                        return false;
-                    }
-                }
-                parents.pop();
-                return true;
-            },
-
-            "object": function (b, a) {
-                var i, j, loop;
-                var eq = true; // unless we can proove it
-                var aProperties = [], bProperties = []; // collection of strings
-
-                // comparing constructors is more strict than using instanceof
-                if ( a.constructor !== b.constructor) {
-                    return false;
-                }
-
-                // stack constructor before traversing properties
-                callers.push(a.constructor);
-                //track reference to avoid circular references
-                parents.push(a);
-                
-                for (i in a) { // be strict: don't ensures hasOwnProperty and go deep
-                    loop = false;
-                    for(j=0;j<parents.length;j++){
-                        if(parents[j] === a[i])
-                            loop = true; //don't go down the same path twice
-                    }
-                    aProperties.push(i); // collect a's properties
-
-                    if (!loop && ! innerEquiv(a[i], b[i])) {
-                        eq = false;
-                        break;
-                    }
-                }
-
-                callers.pop(); // unstack, we are done
-                parents.pop();
-
-                for (i in b) {
-                    bProperties.push(i); // collect b's properties
-                }
-
-                // Ensures identical properties name
-                return eq && innerEquiv(aProperties.sort(), bProperties.sort());
-            }
-        };
-    }();
-
-    innerEquiv = function () { // can take multiple arguments
-        var args = Array.prototype.slice.apply(arguments);
-        if (args.length < 2) {
-            return true; // end transition
-        }
-
-        return (function (a, b) {
-            if (a === b) {
-                return true; // catch the most you can
-            } else if (a === null || b === null || typeof a === "undefined" || typeof b === "undefined" || QUnit.objectType(a) !== QUnit.objectType(b)) {
-                return false; // don't lose time with error prone cases
-            } else {
-                return bindCallbacks(a, callbacks, [b, a]);
-            }
-
-        // apply transition with (1..n) arguments
-        })(args[0], args[1]) && arguments.callee.apply(this, args.splice(1, args.length -1));
-    };
-
-    return innerEquiv;
-
-}();
-
-/**
- * jsDump
- * Copyright (c) 2008 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
- * Licensed under BSD (http://www.opensource.org/licenses/bsd-license.php)
- * Date: 5/15/2008
- * @projectDescription Advanced and extensible data dumping for Javascript.
- * @version 1.0.0
- * @author Ariel Flesler
- * @link {http://flesler.blogspot.com/2008/05/jsdump-pretty-dump-of-any-javascript.html}
- */
-QUnit.jsDump = (function() {
-	function quote( str ) {
-		return '"' + str.toString().replace(/"/g, '\\"') + '"';
-	};
-	function literal( o ) {
-		return o + '';	
-	};
-	function join( pre, arr, post ) {
-		var s = jsDump.separator(),
-			base = jsDump.indent(),
-			inner = jsDump.indent(1);
-		if ( arr.join )
-			arr = arr.join( ',' + s + inner );
-		if ( !arr )
-			return pre + post;
-		return [ pre, inner + arr, base + post ].join(s);
-	};
-	function array( arr ) {
-		var i = arr.length,	ret = Array(i);					
-		this.up();
-		while ( i-- )
-			ret[i] = this.parse( arr[i] );				
-		this.down();
-		return join( '[', ret, ']' );
-	};
-	
-	var reName = /^function (\w+)/;
-	
-	var jsDump = {
-		parse:function( obj, type ) { //type is used mostly internally, you can fix a (custom)type in advance
-			var	parser = this.parsers[ type || this.typeOf(obj) ];
-			type = typeof parser;			
-			
-			return type == 'function' ? parser.call( this, obj ) :
-				   type == 'string' ? parser :
-				   this.parsers.error;
-		},
-		typeOf:function( obj ) {
-			var type;
-			if ( obj === null ) {
-				type = "null";
-			} else if (typeof obj === "undefined") {
-				type = "undefined";
-			} else if (QUnit.is("RegExp", obj)) {
-				type = "regexp";
-			} else if (QUnit.is("Date", obj)) {
-				type = "date";
-			} else if (QUnit.is("Function", obj)) {
-				type = "function";
-			} else if (typeof obj.setInterval !== undefined && typeof obj.document !== "undefined" && typeof obj.nodeType === "undefined") {
-				type = "window";
-			} else if (obj.nodeType === 9) {
-				type = "document";
-			} else if (obj.nodeType) {
-				type = "node";
-			} else if (typeof obj === "object" && typeof obj.length === "number" && obj.length >= 0) {
-				type = "array";
-			} else {
-				type = typeof obj;
-			}
-			return type;
-		},
-		separator:function() {
-			return this.multiline ?	this.HTML ? '<br />' : '\n' : this.HTML ? '&nbsp;' : ' ';
-		},
-		indent:function( extra ) {// extra can be a number, shortcut for increasing-calling-decreasing
-			if ( !this.multiline )
-				return '';
-			var chr = this.indentChar;
-			if ( this.HTML )
-				chr = chr.replace(/\t/g,'   ').replace(/ /g,'&nbsp;');
-			return Array( this._depth_ + (extra||0) ).join(chr);
-		},
-		up:function( a ) {
-			this._depth_ += a || 1;
-		},
-		down:function( a ) {
-			this._depth_ -= a || 1;
-		},
-		setParser:function( name, parser ) {
-			this.parsers[name] = parser;
-		},
-		// The next 3 are exposed so you can use them
-		quote:quote, 
-		literal:literal,
-		join:join,
-		//
-		_depth_: 1,
-		// This is the list of parsers, to modify them, use jsDump.setParser
-		parsers:{
-			window: '[Window]',
-			document: '[Document]',
-			error:'[ERROR]', //when no parser is found, shouldn't happen
-			unknown: '[Unknown]',
-			'null':'null',
-			'undefined':'undefined',
-			'function':function( fn ) {
-				var ret = 'function',
-					name = 'name' in fn ? fn.name : (reName.exec(fn)||[])[1];//functions never have name in IE
-				if ( name )
-					ret += ' ' + name;
-				ret += '(';
-				
-				ret = [ ret, QUnit.jsDump.parse( fn, 'functionArgs' ), '){'].join('');
-				return join( ret, QUnit.jsDump.parse(fn,'functionCode'), '}' );
-			},
-			array: array,
-			nodelist: array,
-			arguments: array,
-			object:function( map ) {
-				var ret = [ ];
-				QUnit.jsDump.up();
-				for ( var key in map )
-					ret.push( QUnit.jsDump.parse(key,'key') + ': ' + QUnit.jsDump.parse(map[key]) );
-				QUnit.jsDump.down();
-				return join( '{', ret, '}' );
-			},
-			node:function( node ) {
-				var open = QUnit.jsDump.HTML ? '&lt;' : '<',
-					close = QUnit.jsDump.HTML ? '&gt;' : '>';
-					
-				var tag = node.nodeName.toLowerCase(),
-					ret = open + tag;
-					
-				for ( var a in QUnit.jsDump.DOMAttrs ) {
-					var val = node[QUnit.jsDump.DOMAttrs[a]];
-					if ( val )
-						ret += ' ' + a + '=' + QUnit.jsDump.parse( val, 'attribute' );
-				}
-				return ret + close + open + '/' + tag + close;
-			},
-			functionArgs:function( fn ) {//function calls it internally, it's the arguments part of the function
-				var l = fn.length;
-				if ( !l ) return '';				
-				
-				var args = Array(l);
-				while ( l-- )
-					args[l] = String.fromCharCode(97+l);//97 is 'a'
-				return ' ' + args.join(', ') + ' ';
-			},
-			key:quote, //object calls it internally, the key part of an item in a map
-			functionCode:'[code]', //function calls it internally, it's the content of the function
-			attribute:quote, //node calls it internally, it's an html attribute value
-			string:quote,
-			date:quote,
-			regexp:literal, //regex
-			number:literal,
-			'boolean':literal
-		},
-		DOMAttrs:{//attributes to dump from nodes, name=>realName
-			id:'id',
-			name:'name',
-			'class':'className'
-		},
-		HTML:false,//if true, entities are escaped ( <, >, \t, space and \n )
-		indentChar:'  ',//indentation unit
-		multiline:true //if true, items in a collection, are separated by a \n, else just a space.
-	};
-
-	return jsDump;
-})();
-
-// from Sizzle.js
-function getText( elems ) {
-	var ret = "", elem;
-
-	for ( var i = 0; elems[i]; i++ ) {
-		elem = elems[i];
-
-		// Get the text from text nodes and CDATA nodes
-		if ( elem.nodeType === 3 || elem.nodeType === 4 ) {
-			ret += elem.nodeValue;
-
-		// Traverse everything else, except comment nodes
-		} else if ( elem.nodeType !== 8 ) {
-			ret += getText( elem.childNodes );
-		}
-	}
-
-	return ret;
-};
-
-/*
- * Javascript Diff Algorithm
- *  By John Resig (http://ejohn.org/)
- *  Modified by Chu Alan "sprite"
- *
- * Released under the MIT license.
- *
- * More Info:
- *  http://ejohn.org/projects/javascript-diff-algorithm/
- *  
- * Usage: QUnit.diff(expected, actual)
- * 
- * QUnit.diff("the quick brown fox jumped over", "the quick fox jumps over") == "the  quick <del>brown </del> fox <del>jumped </del><ins>jumps </ins> over"
- */
-QUnit.diff = (function() {
-	function diff(o, n){
-		var ns = new Object();
-		var os = new Object();
-		
-		for (var i = 0; i < n.length; i++) {
-			if (ns[n[i]] == null) 
-				ns[n[i]] = {
-					rows: new Array(),
-					o: null
-				};
-			ns[n[i]].rows.push(i);
-		}
-		
-		for (var i = 0; i < o.length; i++) {
-			if (os[o[i]] == null) 
-				os[o[i]] = {
-					rows: new Array(),
-					n: null
-				};
-			os[o[i]].rows.push(i);
-		}
-		
-		for (var i in ns) {
-			if (ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1) {
-				n[ns[i].rows[0]] = {
-					text: n[ns[i].rows[0]],
-					row: os[i].rows[0]
-				};
-				o[os[i].rows[0]] = {
-					text: o[os[i].rows[0]],
-					row: ns[i].rows[0]
-				};
-			}
-		}
-		
-		for (var i = 0; i < n.length - 1; i++) {
-			if (n[i].text != null && n[i + 1].text == null && n[i].row + 1 < o.length && o[n[i].row + 1].text == null &&
-			n[i + 1] == o[n[i].row + 1]) {
-				n[i + 1] = {
-					text: n[i + 1],
-					row: n[i].row + 1
-				};
-				o[n[i].row + 1] = {
-					text: o[n[i].row + 1],
-					row: i + 1
-				};
-			}
-		}
-		
-		for (var i = n.length - 1; i > 0; i--) {
-			if (n[i].text != null && n[i - 1].text == null && n[i].row > 0 && o[n[i].row - 1].text == null &&
-			n[i - 1] == o[n[i].row - 1]) {
-				n[i - 1] = {
-					text: n[i - 1],
-					row: n[i].row - 1
-				};
-				o[n[i].row - 1] = {
-					text: o[n[i].row - 1],
-					row: i - 1
-				};
-			}
-		}
-		
-		return {
-			o: o,
-			n: n
-		};
-	}
-	
-	return function(o, n){
-		o = o.replace(/\s+$/, '');
-		n = n.replace(/\s+$/, '');
-		var out = diff(o == "" ? [] : o.split(/\s+/), n == "" ? [] : n.split(/\s+/));
-
-		var str = "";
-		
-		var oSpace = o.match(/\s+/g);
-		if (oSpace == null) {
-			oSpace = [" "];
-		}
-		else {
-			oSpace.push(" ");
-		}
-		var nSpace = n.match(/\s+/g);
-		if (nSpace == null) {
-			nSpace = [" "];
-		}
-		else {
-			nSpace.push(" ");
-		}
-		
-		if (out.n.length == 0) {
-			for (var i = 0; i < out.o.length; i++) {
-				str += '<del>' + out.o[i] + oSpace[i] + "</del>";
-			}
-		}
-		else {
-			if (out.n[0].text == null) {
-				for (n = 0; n < out.o.length && out.o[n].text == null; n++) {
-					str += '<del>' + out.o[n] + oSpace[n] + "</del>";
-				}
-			}
-			
-			for (var i = 0; i < out.n.length; i++) {
-				if (out.n[i].text == null) {
-					str += '<ins>' + out.n[i] + nSpace[i] + "</ins>";
-				}
-				else {
-					var pre = "";
-					
-					for (n = out.n[i].row + 1; n < out.o.length && out.o[n].text == null; n++) {
-						pre += '<del>' + out.o[n] + oSpace[n] + "</del>";
-					}
-					str += " " + out.n[i].text + nSpace[i] + pre;
-				}
-			}
-		}
-		
-		return str;
-	};
-})();
-
-})(this);
diff --git a/Res/mobile-spec/test-runner.js b/Res/mobile-spec/test-runner.js
deleted file mode 100644
index a8ce730..0000000
--- a/Res/mobile-spec/test-runner.js
+++ /dev/null
@@ -1,26 +0,0 @@
-// Prevent QUnit from running when the DOM load event fires
-QUnit.config.autostart = false;
-sessionStorage.clear();
-
-var Tests = function() {
-    this.TEST_TIMEOUT = 500;
-};
-
-document.addEventListener('DOMContentLoaded', function() {
-    document.addEventListener('deviceready', function() {
-        var tests = new Tests();
-
-        // Each group of tests are declared as a function in the object `Tests`.
-        // A group of tests are identified by a name that contains the word 'Tests'.
-        //
-        // Load each group of tests into QUnit
-        for (var t in tests) {
-            if (t.indexOf('Tests') > -1) {
-                tests[t]();
-            }
-        }
-        
-        // Start the QUnit test suite
-        QUnit.start();
-    }, false);
-}, false);
diff --git a/Res/mobile-spec/tests/accelerometer.tests.js b/Res/mobile-spec/tests/accelerometer.tests.js
deleted file mode 100644
index 3a3f0d5..0000000
--- a/Res/mobile-spec/tests/accelerometer.tests.js
+++ /dev/null
@@ -1,55 +0,0 @@
-Tests.prototype.AccelerometerTests = function() {
-	module('Accelerometer (navigator.accelerometer)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.accelerometer != null, "navigator.accelerometer should not be null.");
-	});
-	test("should contain a getCurrentAcceleration function", function() {
-		expect(2);
-		ok(typeof navigator.accelerometer.getCurrentAcceleration != 'undefined' && navigator.accelerometer.getCurrentAcceleration != null, "navigator.accelerometer.getCurrentAcceleration should not be null.");
-		ok(typeof navigator.accelerometer.getCurrentAcceleration == 'function', "navigator.accelerometer.getCurrentAcceleration should be a function.");
-	});
-	test("getCurrentAcceleration success callback should be called with an Acceleration object", function() {
-		expect(7);
-		QUnit.stop(this.TEST_TIMEOUT);
-		var win = function(a) {
-			ok(typeof a == 'object', "Acceleration object returned in getCurrentAcceleration success callback should be of type 'object'.");
-			ok(a.x != null, "Acceleration object returned in getCurrentAcceleration success callback should have an 'x' property.");
-			ok(typeof a.x == 'number', "Acceleration object's 'x' property returned in getCurrentAcceleration success callback should be of type 'number'.");
-			ok(a.y != null, "Acceleration object returned in getCurrentAcceleration success callback should have a 'y' property.");
-			ok(typeof a.y == 'number', "Acceleration object's 'y' property returned in getCurrentAcceleration success callback should be of type 'number'.");
-			ok(a.z != null, "Acceleration object returned in getCurrentAcceleration success callback should have a 'z' property.");
-			ok(typeof a.z == 'number', "Acceleration object's 'z' property returned in getCurrentAcceleration success callback should be of type 'number'.");
-			start();
-		};
-		var fail = function() { start(); };
-		navigator.accelerometer.getCurrentAcceleration(win, fail);
-	});
-	test("should contain a watchAcceleration function", function() {
-		expect(2);
-		ok(typeof navigator.accelerometer.watchAcceleration != 'undefined' && navigator.accelerometer.watchAcceleration != null, "navigator.accelerometer.watchAcceleration should not be null.");
-		ok(typeof navigator.accelerometer.watchAcceleration == 'function', "navigator.accelerometer.watchAcceleration should be a function.");
-	});
-	test("should contain a clearWatch function", function() {
-		expect(2);
-		ok(typeof navigator.accelerometer.clearWatch != 'undefined' && navigator.accelerometer.clearWatch != null, "navigator.accelerometer.clearWatch should not be null.");
-		ok(typeof navigator.accelerometer.clearWatch == 'function', "navigator.accelerometer.clearWatch should be a function!");
-	});
-	module('Acceleration model');
-	test("should be able to define a new Acceleration object with x, y, z and timestamp properties.", function () {
-		expect(9);
-		var x = 1;
-		var y = 2;
-		var z = 3;
-		var a = new Acceleration(x, y, z);
-		ok(a != null, "new Acceleration object should not be null.");
-		ok(typeof a == 'object', "new Acceleration object should be of type 'object'.");
-		ok(a.x != null, "new Acceleration object should have an 'x' property.");
-		equals(a.x, x, "new Acceleration object should have 'x' property equal to first parameter passed in Acceleration constructor.");
-		ok(a.y != null, "new Acceleration object should have a 'y' property.");
-		equals(a.y, y, "new Acceleration object should have 'y' property equal to second parameter passed in Acceleration constructor.");
-		ok(a.z != null, "new Acceleration object should have a 'z' property.");
-		equals(a.z, z, "new Acceleration object should have 'z' property equal to third parameter passed in Acceleration constructor.");
-		ok(a.timestamp != null, "new Acceleration object should have a 'timestamp' property.");
-	});
-};
diff --git a/Res/mobile-spec/tests/camera.tests.js b/Res/mobile-spec/tests/camera.tests.js
deleted file mode 100644
index 3aea2d3..0000000
--- a/Res/mobile-spec/tests/camera.tests.js
+++ /dev/null
@@ -1,12 +0,0 @@
-Tests.prototype.CameraTests = function() {	
-	module('Camera (navigator.camera)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.camera != null, "navigator.camera should not be null.");
-	});
-	test("should contain a getPicture function", function() {
-		expect(2);
-		ok(typeof navigator.camera.getPicture != 'undefined' && navigator.camera.getPicture != null, "navigator.camera.getPicture should not be null.");
-		ok(typeof navigator.camera.getPicture == 'function', "navigator.camera.getPicture should be a function.");
-	});
-};
\ No newline at end of file
diff --git a/Res/mobile-spec/tests/capture.tests.js b/Res/mobile-spec/tests/capture.tests.js
deleted file mode 100644
index a05da15..0000000
--- a/Res/mobile-spec/tests/capture.tests.js
+++ /dev/null
@@ -1,76 +0,0 @@
-Tests.prototype.CaptureTests = function() {  
-    module('Capture (navigator.device.capture)');
-    test("should exist", function() {
-        expect(2);
-        ok(navigator.device != null, "navigator.device should not be null.");
-        ok(navigator.device.capture != null, "navigator.device.capture should not be null.");
-    });
-    test("should have the correct properties ", function() {
-        expect(3);
-        ok(typeof navigator.device.capture.supportedAudioFormats != 'undefined' && navigator.device.capture.supportedAudioFormats != null , "there should be a supported audio formats property");
-        ok(typeof navigator.device.capture.supportedImageFormats != 'undefined' && navigator.device.capture.supportedImageFormats != null , "there should be a supported image formats property");
-        ok(typeof navigator.device.capture.supportedVideoFormats != 'undefined' && navigator.device.capture.supportedVideoFormats != null , "there should be a supported video formats property");
-    });
-    test("should contain a captureAudio function", function() {
-        expect(2);
-        ok(typeof navigator.device.capture.captureAudio != 'undefined' && navigator.device.capture.captureAudio != null, "navigator.device.capture.captureAudio should not be null.");
-        ok(typeof navigator.device.capture.captureAudio == 'function', "navigator.device.capture.captureAudio should be a function.");
-    });
-    test("should contain a captureImage function", function() {
-        expect(2);
-        ok(typeof navigator.device.capture.captureImage != 'undefined' && navigator.device.capture.captureImage != null, "navigator.device.capture.captureImage should not be null.");
-        ok(typeof navigator.device.capture.captureImage == 'function', "navigator.device.capture.captureImage should be a function.");
-    });
-    test("should contain a captureVideo function", function() {
-        expect(2);
-        ok(typeof navigator.device.capture.captureVideo != 'undefined' && navigator.device.capture.captureVideo != null, "navigator.device.capture.captureVideo should not be null.");
-        ok(typeof navigator.device.capture.captureVideo == 'function', "navigator.device.capture.captureVideo should be a function.");
-    });
-	module('CaptureAudioOptions');
-    test("CaptureAudioOptions constructor should exist", function() {
-        expect(2);
-        var options = new CaptureAudioOptions();
-        ok(options !== null, "CaptureAudioOptions object should not be null.");
-        ok(typeof options.limit !== 'undefined', "CaptureAudioOptions object should have a 'limit' property.");
-    });
-    module('CaptureImageOptions');
-    test("CaptureImageOptions constructor should exist", function() {
-        expect(2);
-        var options = new CaptureImageOptions();
-        ok(options !== null, "CaptureImageOptions object should not be null.");
-        ok(typeof options.limit !== 'undefined', "CaptureImageOptions object should have a 'limit' property.");
-    });
-    module('CaptureVideoOptions');
-    test("CaptureVideoOptions constructor should exist", function() {
-        expect(3);
-        var options = new CaptureVideoOptions();
-        ok(options !== null, "CaptureVideoOptions object should not be null.");
-        ok(typeof options.limit !== 'undefined', "CaptureVideoOptions object should have a 'limit' property.");
-        ok(typeof options.duration !== 'undefined', "CaptureVideoOptions object should have a 'duration' property.");
-    });
-    module('CaptureError interface');
-    test("CaptureError constants should be defined", function() {
-        expect(4);
-        equal(CaptureError.CAPTURE_INTERNAL_ERR, 0, "CaptureError.CAPTURE_INTERNAL_ERR should be defined");
-        equal(CaptureError.CAPTURE_APPLICATION_BUSY, 1, "CaptureError.CAPTURE_APPLICATION_BUSY should be defined");
-        equal(CaptureError.CAPTURE_INVALID_ARGUMENT, 0, "CaptureError.CAPTURE_INVALID_ARGUMENT should be defined");
-        equal(CaptureError.CAPTURE_NO_MEDIA_FILES, 0, "CaptureError.CAPTURE_NO_MEDIA_FILES should be defined");
-    });
-    test("CaptureError properties should exist", function() {
-        expect(2);
-        var error = new CaptureError();
-        ok(error !== null, "CaptureError object should not be null.");
-        ok(typeof error.code !== 'undefined', "CaptureError object should have a 'code' property.");
-    });
-    module('MediaFileData');
-    test("MediaFileData constructor should exist", function() {
-        expect(6);
-        var fileData = new MediaFileData();
-        ok(fileData !== null, "MediaFileData object should not be null.");
-        ok(typeof fileData.bitrate !== 'undefined', "MediaFileData object should have a 'bitrate' property.");
-        ok(typeof fileData.codecs !== 'undefined', "MediaFileData object should have a 'codecs' property.");
-        ok(typeof fileData.duration !== 'undefined', "MediaFileData object should have a 'duration' property.");
-        ok(typeof fileData.height !== 'undefined', "MediaFileData object should have a 'height' property.");
-        ok(typeof fileData.width !== 'undefined', "MediaFileData object should have a 'width' property.");
-    });
-};
\ No newline at end of file
diff --git a/Res/mobile-spec/tests/contacts.tests.js b/Res/mobile-spec/tests/contacts.tests.js
deleted file mode 100644
index 65cc1ba..0000000
--- a/Res/mobile-spec/tests/contacts.tests.js
+++ /dev/null
@@ -1,180 +0,0 @@
-Tests.prototype.ContactsTests = function() {
-	module("Contacts (navigator.service.contacts)");
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.service.contacts != null, "navigator.service.contacts should not be null.");
-	});	
-	test("should contain a find function", function() {
-		expect(2);
-		ok(typeof navigator.service.contacts.find != 'undefined' && navigator.service.contacts.find != null, "navigator.service.contacts.find should not be null.");
-		ok(typeof navigator.service.contacts.find == 'function', "navigator.service.contacts.find should be a function.");
-	});
-	test("contacts.find success callback should be called with an array", function() {
-		expect(2);
-		QUnit.stop(this.TEST_TIMEOUT);
-		var win = function(result) {
-			ok(typeof result == 'object', "Object returned in contacts.find success callback is of type 'object' (actually array).");
-			ok(typeof result.length == 'number', "Object returned in contacts.find success callback has a length property which is numerical.");
-			QUnit.start();
-		};
-		var fail = function() { QUnit.start(); };
-		var obj = new ContactFindOptions();
-		obj.filter="test";
-		obj.multiple=true;
-		navigator.service.contacts.find(["displayName", "name", "phoneNumbers", "emails"], win, fail, obj);
-	});	
-	test("should contain a create function", function() {
-		expect(2);
-		ok(typeof navigator.service.contacts.create != 'undefined' && navigator.service.contacts.create != null, "navigator.service.contacts.create should not be null.");
-		ok(typeof navigator.service.contacts.create == 'function', "navigator.service.contacts.create should be a function.");
-	});
-	test("contacts.create should return a Contact object", function() {
-		expect(9);
-		var obj = navigator.service.contacts.create({"displayName": "test name", "gender": "male", "note": "my note", "name": {"formatted": "Mr. Test Name"}, "emails": [{"value": "here@there.com"}, {"value": "there@here.com"}]});		
-		ok(obj != 'undefined' && obj != null, "navigator.service.contacts.create should return a Contact object.");
-		ok(obj.displayName == 'test name', "Contact should contain a displayName property.");
-		ok(obj.gender == 'male', "Contact should contain a gender property.");
-		ok(obj.note == 'my note', "Contact should contain a note property.");
-		ok(obj.name.formatted == 'Mr. Test Name', "Contact should contain a name.formatted property.");
-		ok(obj.emails.length == 2, "Contact should contain and array of emails with 2 entries");
-		ok(obj.emails[0].value == 'here@there.com', "Contact.emails[1] should contain a value.");
-		ok(obj.emails[1].value == 'there@here.com', "Contact.emails[2] should contain a value.");	
-		ok(obj.birthday == null, "Contact object should not contain a birthday property.");
-	});
-	module("Contact model");
-	test("should be able to define a Contact object", function() {
-		expect(18);
-		var contact = new Contact("a", "b", new ContactName("a", "b", "c", "d", "e", "f"), "c", [], [], [], [], [], "d", "f", "h", "i",  
-				[], [], [], "l");
-		ok(contact != null, "new Contact() should not be null.");
-		ok(typeof contact.id != 'undefined' && contact.id != null && contact.id == "a", "new Contact() should include a 'id' property.");
-		ok(typeof contact.displayName != 'undefined' && contact.displayName != null && contact.displayName == "b", "new Contact() should include a 'displayName' property.");
-		ok(typeof contact.name != 'undefined' && contact.name != null && contact.name.formatted == "a", "new Contact() should include a 'name' property.");
-		ok(typeof contact.nickname != 'undefined' && contact.nickname != null && contact.nickname == "c", "new Contact() should include a 'nickname' property.");
-		ok(typeof contact.phoneNumbers != 'undefined' && contact.phoneNumbers != null, "new Contact() should include a 'phoneNumbers' property.");
-		ok(typeof contact.emails != 'undefined' && contact.emails != null, "new Contact() should include a 'emails' property.");
-		ok(typeof contact.addresses != 'undefined' && contact.addresses != null, "new Contact() should include a 'addresses' property.");
-		ok(typeof contact.ims != 'undefined' && contact.ims != null, "new Contact() should include a 'ims' property.");
-		ok(typeof contact.organizations != 'undefined' && contact.organizations != null, "new Contact() should include a 'organizations' property.");
-		ok(typeof contact.revision != 'undefined' && contact.revision != null && contact.revision == "d", "new Contact() should include a 'revision' property.");
-		ok(typeof contact.birthday != 'undefined' && contact.birthday != null && contact.birthday == "f", "new Contact() should include a 'birthday' property.");
-		ok(typeof contact.gender != 'undefined' && contact.gender != null && contact.gender == "h", "new Contact() should include a 'gender' property.");
-		ok(typeof contact.note != 'undefined' && contact.note != null && contact.note == "i", "new Contact() should include a 'note' property.");
-		ok(typeof contact.photos != 'undefined' && contact.photos != null, "new Contact() should include a 'photos' property.");
-		ok(typeof contact.categories != 'undefined' && contact.categories != null, "new Contact() should include a 'categories' property.");
-		ok(typeof contact.urls != 'undefined' && contact.urls != null, "new Contact() should include a 'urls' property.");
-		ok(typeof contact.timezone != 'undefined' && contact.timezone != null && contact.timezone == "l", "new Contact() should include a 'timezone' property.");
-	});	
-	test("should be able to define a ContactName object", function() {
-		expect(7);
-		var contactName = new ContactName("Dr. First Last Jr.", "Last", "First", "Middle", "Dr.", "Jr.");
-		ok(contactName != null, "new ContactName() should not be null.");
-		ok(typeof contactName.formatted != 'undefined' && contactName.formatted != null && contactName.formatted == "Dr. First Last Jr.", "new ContactName() should include a 'formatted' property.");
-		ok(typeof contactName.familyName != 'undefined' && contactName.familyName != null && contactName.familyName == "Last", "new ContactName() should include a 'familyName' property.");
-		ok(typeof contactName.givenName != 'undefined' && contactName.givenName != null && contactName.givenName == "First", "new ContactName() should include a 'givenName' property.");
-		ok(typeof contactName.middleName != 'undefined' && contactName.middleName != null && contactName.middleName == "Middle", "new ContactName() should include a 'middleName' property.");
-		ok(typeof contactName.honorificPrefix != 'undefined' && contactName.honorificPrefix != null && contactName.honorificPrefix == "Dr.", "new ContactName() should include a 'honorificPrefix' property.");
-		ok(typeof contactName.honorificSuffix != 'undefined' && contactName.honorificSuffix != null && contactName.honorificSuffix == "Jr.", "new ContactName() should include a 'honorificSuffix' property.");
-	});	
-	test("should be able to define a ContactField object", function() {
-		expect(4);
-		var contactField = new ContactField("home", "8005551212", true);
-		ok(contactField != null, "new ContactField() should not be null.");
-		ok(typeof contactField.type != 'undefined' && contactField.type != null && contactField.type == "home", "new ContactField() should include a 'type' property.");
-		ok(typeof contactField.value != 'undefined' && contactField.value != null && contactField.value == "8005551212", "new ContactField() should include a 'value' property.");
-		ok(typeof contactField.pref != 'undefined' && contactField.pref != null && contactField.pref == true, "new ContactField() should include a 'pref' property.");
-	});	
-	test("should be able to define a ContactAddress object", function() {
-		expect(7);
-		var contactAddress = new ContactAddress("a","b","c","d","e","f");
-		ok(contactAddress != null, "new ContactAddress() should not be null.");
-		ok(typeof contactAddress.formatted != 'undefined' && contactAddress.formatted != null && contactAddress.formatted == "a", "new ContactAddress() should include a 'formatted' property.");
-		ok(typeof contactAddress.streetAddress != 'undefined' && contactAddress.streetAddress != null && contactAddress.streetAddress == "b", "new ContactAddress() should include a 'streetAddress' property.");
-		ok(typeof contactAddress.locality != 'undefined' && contactAddress.locality != null && contactAddress.locality == "c", "new ContactAddress() should include a 'locality' property.");
-		ok(typeof contactAddress.region != 'undefined' && contactAddress.region != null && contactAddress.region == "d", "new ContactAddress() should include a 'region' property.");
-		ok(typeof contactAddress.postalCode != 'undefined' && contactAddress.postalCode != null && contactAddress.postalCode == "e", "new ContactAddress() should include a 'postalCode' property.");
-		ok(typeof contactAddress.country != 'undefined' && contactAddress.country != null && contactAddress.country == "f", "new ContactAddress() should include a 'country' property.");
-	});	
-	test("should be able to define a ContactOrganization object", function() {
-		expect(4);
-		var contactOrg = new ContactOrganization("a","b","c","d","e","f","g");
-		ok(contactOrg != null, "new ContactOrganization() should not be null.");
-		ok(typeof contactOrg.name != 'undefined' && contactOrg.name != null && contactOrg.name == "a", "new ContactOrganization() should include a 'name' property.");
-		ok(typeof contactOrg.department != 'undefined' && contactOrg.department != null && contactOrg.department == "b", "new ContactOrganization() should include a 'department' property.");
-		ok(typeof contactOrg.title != 'undefined' && contactOrg.title != null && contactOrg.title == "c", "new ContactOrganization() should include a 'title' property.");
-	});	
-	test("should be able to define a ContactFindOptions object", function() {
-		expect(4);
-		var contactFindOptions = new ContactFindOptions("a", true, "b");
-		ok(contactFindOptions != null, "new ContactFindOptions() should not be null.");
-		ok(typeof contactFindOptions.filter != 'undefined' && contactFindOptions.filter != null && contactFindOptions.filter == "a", "new ContactFindOptions() should include a 'filter' property.");
-		ok(typeof contactFindOptions.multiple != 'undefined' && contactFindOptions.multiple != null && contactFindOptions.multiple == true, "new ContactFindOptions() should include a 'multiple' property.");
-		ok(typeof contactFindOptions.updatedSince != 'undefined' && contactFindOptions.updatedSince != null && contactFindOptions.updatedSince == "b", "new ContactFindOptions() should include a 'updatedSince' property.");
-	});	
-	module("Contact Object");
-	test("should contain a clone function", function() {
-		expect(2);
-		var contact = new Contact();
-		ok(typeof contact.clone != 'undefined' && contact.clone != null, "contact.clone should not be null.");
-		ok(typeof contact.clone == 'function', "contact.clone should be a function.");
-	});
-	test("clone function should make deep copy of Contact Object", function() {
-		expect(8);
-		var contact = new Contact();
-		contact.id=1;
-		contact.displayName="Test Name";
-		contact.nickname="Testy";
-		contact.gender="male";
-		contact.note="note to be cloned";
-		contact.name = new ContactName("Mr. Test Name");
-		
-		var clonedContact = contact.clone();
-		
-		ok(contact.id == 1, "contact.id should be 1.");
-		ok(clonedContact.id == null, "clonedContact.id should be null.");
-		ok(clonedContact.displayName == contact.displayName, "displayName's should be equal");
-		ok(clonedContact.nickname == contact.nickname, "nickname's should be equal");
-		ok(clonedContact.gender == contact.gender, "gender's should be equal");
-		ok(clonedContact.note == contact.note, "note's should be equal");
-		ok(clonedContact.name.formatted == contact.name.formatted, "name.formatted's should be equal");
-		ok(clonedContact.connected == contact.connected, "connected's should be equal (null)");
-	});
-	test("should contain a remove function", function() {
-		expect(2);
-		var contact = new Contact();
-		ok(typeof contact.remove != 'undefined' && contact.remove != null, "contact.remove should not be null.");
-		ok(typeof contact.remove == 'function', "contact.remove should be a function.");
-	});
-	test("calling remove on a contact has an id of null should return ContactError.NOT_FOUND_ERROR", function() {
-        QUnit.stop(this.TEST_TIMEOUT);
-		expect(2);
-		var win = function(result) {
-		};
-		var fail = function(result) {
-			ok(typeof result == 'object', "Object returned in contact.remove failure callback is of type 'object' (actually ContactError).");
-			ok(result.code == ContactError.NOT_FOUND_ERROR, "Object returned in contacts.remove failure callback has a code property which equal to ContactError.NOT_FOUND_ERROR.");
-			QUnit.start();
-		};
-		var rmContact = new Contact();
-		rmContact.remove(win, fail);
-	});
-	test("calling remove on a contact that does not exist should return ContactError.NOT_FOUND_ERROR", function() {
-        QUnit.stop(this.TEST_TIMEOUT);
-		expect(2);
-		var win = function(result) {
-		};
-		var fail = function(result) {
-			ok(typeof result == 'object', "Object returned in contact.remove failure callback is of type 'object' (actually ContactError).");
-			ok(result.code == ContactError.NOT_FOUND_ERROR, "Object returned in contacts.remove failure callback has a code property which equal to ContactError.NOT_FOUND_ERROR.");
-			QUnit.start();
-		};
-		var contact = new Contact(99);
-		contact.remove(win, fail);		
-	});
-	test("should contain a save function", function() {
-		expect(2);
-		var contact = new Contact();
-		ok(typeof contact.save != 'undefined' && contact.save != null, "contact.save should not be null.");
-		ok(typeof contact.save == 'function', "contact.save should be a function.");
-	});
-};
diff --git a/Res/mobile-spec/tests/device.tests.js b/Res/mobile-spec/tests/device.tests.js
deleted file mode 100644
index 537aeda..0000000
--- a/Res/mobile-spec/tests/device.tests.js
+++ /dev/null
@@ -1,36 +0,0 @@
-Tests.prototype.DeviceTests = function() {
-	module('Device Information (window.device)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(window.device != null, "window.device should not be null.");
-	});
-	test("should contain a platform specification that is a string", function() {
-		expect(2);
-		ok(typeof window.device.platform != 'undefined' && window.device.platform != null, "window.device.platform should not be null.")
-		ok((new String(window.device.platform)).length > 0, "window.device.platform should contain some sort of description.")
-	});
-	test("should contain a version specification that is a string", function() {
-		expect(2);
-		ok(typeof window.device.version != 'undefined' && window.device.version != null, "window.device.version should not be null.")
-		ok((new String(window.device.version)).length > 0, "window.device.version should contain some kind of description.")
-	});
-	test("should contain a name specification that is a string", function() {
-		expect(2);
-		ok(typeof window.device.name != 'undefined' && window.device.name != null, "window.device.name should not be null.")
-		ok((new String(window.device.name)).length > 0, "window.device.name should contain some kind of description.")
-	});
-	test("should contain a UUID specification that is a string or a number", function() {
-		expect(2);
-		ok(typeof window.device.uuid != 'undefined' && window.device.uuid != null, "window.device.uuid should not be null.")
-		if (typeof window.device.uuid == 'string' || typeof window.device.uuid == 'object') {
-			ok((new String(window.device.uuid)).length > 0, "window.device.uuid, as a string, should have at least one character.")
-		} else {
-			ok(window.device.uuid > 0, "window.device.uuid, as a number, should be greater than 0. (should it, even?)")
-		}
-	});
-	test("should contain a phonegap specification that is a string", function() {
-		expect(2);
-		ok(typeof window.device.phonegap != 'undefined' && window.device.phonegap != null, "window.device.phonegap should not be null.")
-		ok((new String(window.device.phonegap)).length > 0, "window.device.phonegap should contain some kind of description.")
-	});
-};
\ No newline at end of file
diff --git a/Res/mobile-spec/tests/file.tests.js b/Res/mobile-spec/tests/file.tests.js
deleted file mode 100644
index fd293b1..0000000
--- a/Res/mobile-spec/tests/file.tests.js
+++ /dev/null
@@ -1,2379 +0,0 @@
-/**
- * Retrieves root file system entries once, so they don't have to be 
- * repeated for every test (file system shouldn't change during test run). 
- */ 
-var getFileSystemRoot = (function() {
-
-    // private
-    var temp_root, persistent_root;
-
-    var onError = function(error) {
-        console.log('unable to retrieve file system: ' + error.code);
-    };
-    
-    // one-time retrieval of the root file system entry
-    var init = function() {
-        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
-                function(fileSystem) {
-                    persistent_root = fileSystem.root;
-                }, onError);
-        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0,
-                function(fileSystem) {
-                    temp_root = fileSystem.root;
-                }, onError);
-    };
-    document.addEventListener("deviceready", init, true); 
-
-    // public function returns private root entry
-    return function() {
-        // When testing, it is a good idea to run the test suite once for each
-        // file system type.  Just change the return value from this function.  
-        //return temp_root;
-        return persistent_root;
-    };
-}()); // execute immediately
-
-Tests.prototype.FileTests = function() {
-    module('FileError interface');
-    test("FileError constants should be defined", function() {
-        expect(12);
-        equal(FileError.NOT_FOUND_ERR, 1, "FileError.NOT_FOUND_ERR should be defined");
-        equal(FileError.SECURITY_ERR, 2, "FileError.SECURITY_ERR should be defined");
-        equal(FileError.ABORT_ERR, 3, "FileError.ABORT should be defined");
-        equal(FileError.NOT_READABLE_ERR, 4, "FileError.NOT_READABLE_ERR should be defined");
-        equal(FileError.ENCODING_ERR, 5, "FileError.ENCODING_ERR should be defined");
-        equal(FileError.NO_MODIFICATION_ALLOWED_ERR, 6, "FileError.NO_MODIFICATION_ALLOWED_ERR should be defined");
-        equal(FileError.INVALID_STATE_ERR, 7, "FileError.INVALID_STATE_ERR should be defined");
-        equal(FileError.SYNTAX_ERR, 8, "FileError.SYNTAX_ERR should be defined");
-        equal(FileError.INVALID_MODIFICATION_ERR, 9, "FileError.INVALID_MODIFICATION_ERR should be defined");
-        equal(FileError.QUOTA_EXCEEDED_ERR, 10, "FileError.QUOTA_EXCEEDED_ERR should be defined");
-        equal(FileError.TYPE_MISMATCH_ERR, 11, "FileError.TYPE_MISMATCH_ERR should be defined");
-        equal(FileError.PATH_EXISTS_ERR, 12, "FileError.PATH_EXISTS_ERR should be defined");
-    });
-    module('LocalFileSystem interface');
-    test("window.requestFileSystem function should be defined", function() {
-        expect(1);
-        ok(typeof window.requestFileSystem === 'function', "window.requestFileSystem should be a function.");
-    });
-    test("window.resolveLocalFileSystemURI function should be defined", function() {
-        expect(1);
-        ok(typeof window.resolveLocalFileSystemURI === 'function', "window.resolveLocalFileSystemURI should be a function.");
-    });
-    test("File system types should be defined", function() {
-        expect(2);
-        equal(LocalFileSystem.TEMPORARY, 0, "LocalFileSystem.TEMPORARY should be defined");
-        equal(LocalFileSystem.PERSISTENT, 1, "LocalFileSystem.PERSISTENT should be defined");
-    });
-    test("retrieve PERSISTENT file system", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-
-        var testPersistent = function(fileSystem) {
-            ok(typeof fileSystem !== 'undefined' && fileSystem !== null, "window.requestFileSystem should return an object.");
-            ok(typeof fileSystem.name !== 'undefined' && fileSystem.name !== null, "filesystem should include a 'name' property.");
-            equal(fileSystem.name, "persistent", "file system 'name' attribute should be set properly");
-            ok(typeof fileSystem.root !== 'undefined' && fileSystem.root !== null, "filesystem should include a 'root' property.");
-            QUnit.start();
-        };
-        
-        // retrieve PERSISTENT file system
-        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, testPersistent, 
-                function(error) {
-                    console.log('error retrieving file system: ' + error.code);
-                });            
-    });
-    test("retrieve TEMPORARY file system", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-
-        var testTemporary = function(fileSystem) {
-            ok(typeof fileSystem !== 'undefined' && fileSystem !== null, "window.requestFileSystem should return an object.");
-            ok(typeof fileSystem.name !== 'undefined' && fileSystem.name !== null, "filesystem should include a 'name' property.");
-            equal(fileSystem.name, "temporary", "file system 'name' attribute should be set properly");
-            ok(typeof fileSystem.root !== 'undefined' && fileSystem.root !== null, "filesystem should include a 'root' property.");
-            QUnit.start();
-        };
-        
-        // Request the file system
-        window.requestFileSystem(LocalFileSystem.TEMPORARY, 0, testTemporary, 
-                function(error) {
-                    console.log('error retrieving file system: ' + error.code);
-                });            
-    });
-    test("request a file system that is too large", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-
-        var failFS = function(error) {
-            ok(error !== null, "error should not be null.");
-            equal(error.code, FileError.QUOTA_EXCEEDED_ERR, "Shoud receive error code FileError.QUOTA_EXCEEDED_ERR");
-            QUnit.start();
-        };
-        
-        // Request the file system
-        window.requestFileSystem(LocalFileSystem.TEMPORARY, 1000000000000000, null, failFS);
-    });
-    test("request a file system that does not exist", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-
-        var failFS = function(error) {
-            ok(typeof error !== 'undefined' && error !== null, "error should not be null.");
-            equal(error.code, FileError.SYNTAX_ERR, "Shoud receive error code FileError.SYNTAX_ERR");
-            QUnit.start();
-        };
-        
-        // Request the file system
-        window.requestFileSystem(-1, 0, null, failFS);
-    });
-    test("resolve invalid file name", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-
-        var failURI = function(error) {
-            ok(typeof error !== 'undefined' && error !== null, "error should not be null.");
-            equal(error.code, FileError.NOT_FOUND_ERR, "Shoud receive error code FileError.NOT_FOUND_ERR");
-            QUnit.start();
-        };
-        
-        // lookup file system entry
-        window.resolveLocalFileSystemURI("file:///this.is.not.a.valid.file.txt", null, failURI);
-    });
-    test("resolve invalid URI", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-
-        var failURI = function(error) {
-            ok(typeof error !== 'undefined' && error !== null, "error should not be null.");
-            equal(error.code, FileError.ENCODING_ERR, "Shoud receive an error code FileError.ENCODING_ERR");
-            QUnit.start();
-        };
-        
-        // lookup file system entry
-        window.resolveLocalFileSystemURI("/this.is.not.a.valid.url", null, failURI);
-    });
-    module('Metadata interface');
-    test("Metadata constructor should exist", function() {
-        expect(2);
-        var metadata = new Metadata();
-        ok(metadata !== null, "Metadata object should not be null.");
-        ok(typeof metadata.modificationTime !== 'undefined', "Metadata object should have a 'modificationTime' property.");
-    });
-    module('Flags interface');
-    test("Flags constructor should exist", function() {
-        expect(5);
-        var flags = new Flags(false, true);
-        ok(flags !== null, "Flags object should not be null.");
-        ok(typeof flags.create !== 'undefined' && flags.create !== null, "Flags object should have a 'create' property.");
-        equal(flags.create, false, "Flags.create should be set properly");
-        ok(typeof flags.exclusive !== 'undefined' && flags.exclusive !== null, "Flags object should have an 'exclusive' property.");
-        equal(flags.exclusive, true, "flags.exclusive should be set properly")
-    });
-    module('FileSystem interface');
-    test("FileSystem root should be a DirectoryEntry", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(15);
-
-        var root = getFileSystemRoot(),
-            testFSRoot = function(entry) {
-                ok(typeof entry !== 'undefined' && entry !== null, "entry should be non-null");
-                equal(entry.isFile, false, "entry.isFile should be false");
-                equal(entry.isDirectory, true, "entry.isDirectory should be true");
-                ok(typeof entry.name !== 'undefined' && entry.name !== null, "entry should include a 'name' property.");
-                ok(typeof entry.fullPath !== 'undefined' && entry.fullPath !== null, "entry should include a 'fullPath' property.");
-                ok(typeof entry.getMetadata === 'function', "entry object should have a 'getMetadata' function.");
-                ok(typeof entry.moveTo === 'function', "entry object should have a 'moveTo' function.");
-                ok(typeof entry.copyTo === 'function', "entry object should have a 'copyTo' function.");
-                ok(typeof entry.toURI === 'function', "entry object should have a 'toURI' function.");
-                ok(typeof entry.remove === 'function', "entry object should have a 'remove' function.");
-                ok(typeof entry.getParent === 'function', "entry object should have a 'getParent' function.");
-                ok(typeof entry.createReader === 'function', "entry object should have a 'createReader' function.");
-                ok(typeof entry.getFile === 'function', "entry object should have a 'getFile' function.");
-                ok(typeof entry.getDirectory === 'function', "entry object should have a 'getDirectory' function.");
-                ok(typeof entry.removeRecursively === 'function', "entry object should have a 'removeRecursively' function.");
-                QUnit.start();
-		 };
-		 
-		window.resolveLocalFileSystemURI(root.toURI(), testFSRoot, null);
-        
-    });
-    module('DirectoryEntry interface', {
-        // setup function will run before each test
-        setup: function() {
-            this.root = getFileSystemRoot();
-            this.fail = function(error) {
-                console.log('file error: ' + error.code);
-            };
-		   this.unexpectedSuccess = function() {
-				console.log('!!! success function called when not expected !!!');
-		   };
-        }
-    });
-    test("DirectoryEntry.getFile: get Entry for file that does not exist", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var fileName = "de.no.file",
-            filePath = this.root.fullPath + '/' + fileName,
-            that = this,
-            testFile = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "retrieving a file that does not exist is an error");
-                equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-                
-                // cleanup
-                QUnit.start();
-            };
-                
-        // create:false, exclusive:false, file does not exist
-        this.root.getFile(fileName, {create:false}, null, testFile); 
-    });
-    test("DirectoryEntry.getFile: create new file", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(5);
-        
-        var fileName = "de.create.file",
-            filePath = this.root.fullPath + '/' + fileName,
-            that = this,
-            testFile = function(entry) {
-                ok(typeof entry !== 'undefined' && entry !== null, "file entry should not be null");
-                equal(entry.isFile, true, "entry 'isFile' attribute should be true");
-                equal(entry.isDirectory, false, "entry 'isDirectory' attribute should be false");
-                equal(entry.name, fileName, "entry 'name' attribute should be set");
-                equal(entry.fullPath, filePath, "entry 'fullPath' attribute should be set");
-                
-                // cleanup
-                entry.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create:true, exclusive:false, file does not exist
-        this.root.getFile(fileName, {create: true}, testFile, this.fail); 
-    });
-    test("DirectoryEntry.getFile: create new file (exclusive)", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(5);
-        
-        var fileName = "de.create.exclusive.file",
-            filePath = this.root.fullPath + '/' + fileName,
-            that = this,
-            testFile = function(entry) {
-                ok(typeof entry !== 'undefined' && entry !== null, "file entry should not be null");
-                equal(entry.isFile, true, "entry 'isFile' attribute should be true");
-                equal(entry.isDirectory, false, "entry 'isDirectory' attribute should be false");
-                equal(entry.name, fileName, "entry 'name' attribute should be set");
-                equal(entry.fullPath, filePath, "entry 'fullPath' attribute should be set");
-                
-                // cleanup
-                entry.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create:true, exclusive:true, file does not exist
-        this.root.getFile(fileName, {create: true, exclusive:true}, testFile, this.fail); 
-    });
-    test("DirectoryEntry.getFile: create file that already exists", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(5);
-        
-        var fileName = "de.create.existing.file",
-            filePath = this.root.fullPath + '/' + fileName,
-            that = this,
-            getFile = function(file) {
-                // create:true, exclusive:false, file exists
-                that.root.getFile(fileName, {create:true}, testFile, that.fail);             
-            },
-            testFile = function(entry) {
-                ok(typeof entry !== 'undefined' && entry !== null, "file entry should not be null");
-                equal(entry.isFile, true, "entry 'isFile' attribute should be true");
-                equal(entry.isDirectory, false, "entry 'isDirectory' attribute should be false");
-                equal(entry.name, fileName, "entry 'name' attribute should be set");
-                equal(entry.fullPath, filePath, "entry 'fullPath' attribute should be set");
-                
-                // cleanup
-                entry.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create file to kick off test
-        this.root.getFile(fileName, {create:true}, getFile, this.fail); 
-    });
-    test("DirectoryEntry.getFile: create file that already exists (exclusive)", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var fileName = "de.create.exclusive.existing.file",
-            filePath = this.root.fullPath + '/' + fileName,
-            that = this,
-            existingFile,
-            getFile = function(file) {
-                existingFile = file;
-                // create:true, exclusive:true, file exists
-                that.root.getFile(fileName, {create:true, exclusive:true}, null, testFile);             
-            },
-            testFile = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "creating exclusive file that already exists is an error");
-                equal(error.code, FileError.PATH_EXISTS_ERR, "error code should be FileError.PATH_EXISTS_ERR");
-               
-                // cleanup
-                existingFile.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create file to kick off test
-        this.root.getFile(fileName, {create:true}, getFile, this.fail); 
-    });
-    test("DirectoryEntry.getFile: get Entry for existing file", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(5);
-        
-        var fileName = "de.get.file",
-            filePath = this.root.fullPath + '/' + fileName,
-            that = this,
-            getFile = function(file) {
-                // create:false, exclusive:false, file exists
-                that.root.getFile(fileName, {create:false}, testFile, that.fail);             
-            },
-            testFile = function(entry) {
-                ok(typeof entry !== 'undefined' && entry !== null, "file entry should not be null");
-                equal(entry.isFile, true, "entry 'isFile' attribute should be true");
-                equal(entry.isDirectory, false, "entry 'isDirectory' attribute should be false");
-                equal(entry.name, fileName, "entry 'name' attribute should be set");
-                equal(entry.fullPath, filePath, "entry 'fullPath' attribute should be set");
-				
-				// cleanup
-                entry.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create file to kick off test
-        this.root.getFile(fileName, {create:true}, getFile, this.fail); 
-    });
-    test("DirectoryEntry.getFile: get FileEntry for invalid path", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var fileName = "de:invalid:path",
-            that = this,
-            testFile = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "retrieving a file using an invalid path is an error");
-                equal(error.code, FileError.ENCODING_ERR, "error code should be FileError.ENCODING_ERR");
-                
-                // cleanup
-                QUnit.start();
-            };
-                
-        // create:false, exclusive:false, invalid path
-        this.root.getFile(fileName, {create:false}, null, testFile); 
-    });
-    test("DirectoryEntry.getDirectory: get Entry for directory that does not exist", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var dirName = "de.no.dir",
-            dirPath = this.root.fullPath + '/' + dirName,
-            that = this,
-            testDir = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "retrieving a directory that does not exist is an error");
-                equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-                
-                // cleanup
-                QUnit.start();
-            };
-                
-        // create:false, exclusive:false, directory does not exist
-        this.root.getDirectory(dirName, {create:false}, null, testDir); 
-    });
-    test("DirectoryEntry.getDirectory: create new directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(5);
-        
-        var dirName = "de.create.dir",
-            dirPath = this.root.fullPath + '/' + dirName,
-            that = this,
-            testDir = function(directory) {
-                ok(typeof directory !== 'undefined' && directory !== null, "directory entry should not be null");
-                equal(directory.isFile, false, "directory 'isFile' attribute should be false");
-                equal(directory.isDirectory, true, "directory 'isDirectory' attribute should be true");
-                equal(directory.name, dirName, "directory 'name' attribute should be set");
-                equal(directory.fullPath, dirPath, "directory 'fullPath' attribute should be set");
-                
-                // cleanup
-                directory.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create:true, exclusive:false, directory does not exist
-        this.root.getDirectory(dirName, {create: true}, testDir, this.fail); 
-    });
-    test("DirectoryEntry.getDirectory: create new directory (exclusive)", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(5);
-        
-        var dirName = "de.create.exclusive.dir",
-            dirPath = this.root.fullPath + '/' + dirName,
-            that = this,
-            testDir = function(directory) {
-                ok(typeof directory !== 'undefined' && directory !== null, "directory entry should not be null");
-                equal(directory.isFile, false, "directory 'isFile' attribute should be false");
-                equal(directory.isDirectory, true, "directory 'isDirectory' attribute should be true");
-                equal(directory.name, dirName, "directory 'name' attribute should be set");
-                equal(directory.fullPath, dirPath, "directory 'fullPath' attribute should be set");
-               
-                // cleanup
-                directory.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create:true, exclusive:true, directory does not exist
-        this.root.getDirectory(dirName, {create: true, exclusive:true}, testDir, this.fail); 
-    });
-    test("DirectoryEntry.getDirectory: create directory that already exists", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(5);
-        
-        var dirName = "de.create.existing.dir",
-            dirPath = this.root.fullPath + '/' + dirName,
-            that = this,
-            getDir = function(directory) {
-                // create:true, exclusive:false, directory exists
-                that.root.getDirectory(dirName, {create:true}, testDir, that.fail);             
-            },
-            testDir = function(directory) {
-                ok(typeof directory !== 'undefined' && directory !== null, "directory entry should not be null");
-                equal(directory.isFile, false, "directory 'isFile' attribute should be false");
-                equal(directory.isDirectory, true, "directory 'isDirectory' attribute should be true");
-                equal(directory.name, dirName, "directory 'name' attribute should be set");
-                equal(directory.fullPath, dirPath, "directory 'fullPath' attribute should be set");
-                
-                // cleanup
-                directory.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create directory to kick off test
-        this.root.getDirectory(dirName, {create:true}, getDir, this.fail); 
-    });
-    test("DirectoryEntry.getDirectory: create directory that already exists (exclusive)", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var dirName = "de.create.exclusive.existing.dir",
-            dirPath = this.root.fullPath + '/' + dirName,
-            that = this,
-            existingDir,
-            getDir = function(directory) {
-                existingDir = directory;
-                // create:true, exclusive:true, directory exists
-                that.root.getDirectory(dirName, {create:true, exclusive:true}, null, testDir);             
-            },
-            testDir = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "creating exclusive directory that already exists is an error");
-                equal(error.code, FileError.PATH_EXISTS_ERR, "error code should be FileError.PATH_EXISTS_ERR");
-                
-                // cleanup
-                existingDir.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create directory to kick off test
-        this.root.getDirectory(dirName, {create:true}, getDir, this.fail); 
-    });
-    test("DirectoryEntry.getDirectory: get Entry for existing directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(5);
-        
-        var dirName = "de.get.dir",
-            dirPath = this.root.fullPath + '/' + dirName,
-            that = this,
-            getDir = function(directory) {
-                // create:false, exclusive:false, directory exists
-                that.root.getDirectory(dirName, {create:false}, testDir, that.fail);             
-            },
-            testDir = function(directory) {
-                ok(typeof directory !== 'undefined' && directory !== null, "directory entry should not be null");
-                equal(directory.isFile, false, "directory 'isFile' attribute should be false");
-                equal(directory.isDirectory, true, "directory 'isDirectory' attribute should be true");
-                equal(directory.name, dirName, "directory 'name' attribute should be set");
-                equal(directory.fullPath, dirPath, "directory 'fullPath' attribute should be set");
-                
-                // cleanup
-                directory.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create directory to kick off test
-        this.root.getDirectory(dirName, {create:true}, getDir, this.fail); 
-    });
-    test("DirectoryEntry.getDirectory: get DirectoryEntry for invalid path", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var dirName = "de:invalid:path",
-            that = this,
-            testDir = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "retrieving a directory using an invalid path is an error");
-                equal(error.code, FileError.ENCODING_ERR, "error code should be FileError.ENCODING_ERR");
-                
-                // cleanup
-                QUnit.start();
-            };
-                
-        // create:false, exclusive:false, invalid path
-        this.root.getDirectory(dirName, {create:false}, null, testDir); 
-    });
-    test("DirectoryEntry.getDirectory: get DirectoryEntry for existing file", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var fileName = "de.existing.file",
-            existingFile,
-            filePath = this.root.fullPath + '/' + fileName,
-            that = this,
-            getDir = function(file) {
-                existingFile = file;
-                // create:false, exclusive:false, existing file
-                that.root.getDirectory(fileName, {create:false}, null, testDir);             
-            },
-            testDir = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "retrieving directory for existing file is an error");
-                equal(error.code, FileError.TYPE_MISMATCH_ERR, "error code should be FileError.TYPE_MISMATCH_ERR");
-                
-                // cleanup
-                existingFile.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create file to kick off test
-        this.root.getFile(fileName, {create:true}, getDir, this.fail); 
-    });
-    test("DirectoryEntry.getFile: get FileEntry for existing directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var dirName = "de.existing.dir",
-            existingDir,
-            dirPath = this.root.fullPath + '/' + dirName,
-            that = this,
-            getFile = function(directory) {
-                existingDir = directory;
-                // create:false, exclusive:false, existing directory
-                that.root.getFile(dirName, {create:false}, null, testFile);             
-            },
-            testFile = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "retrieving file for existing directory is an error");
-                equal(error.code, FileError.TYPE_MISMATCH_ERR, "error code should be FileError.TYPE_MISMATCH_ERR");
-               
-                // cleanup
-                existingDir.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create directory to kick off test
-        this.root.getDirectory(dirName, {create:true}, getFile, this.fail); 
-    });
-    test("DirectoryEntry.removeRecursively on directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var dirName = "de.removeRecursively",
-            subDirName = "dir",
-            dirPath = this.root.fullPath + '/' + dirName,
-            //subDirPath = this.root.fullPath + '/' + subDirName,
-			subDirPath = dirPath + '/' + subDirName,
-            that = this,
-            entryCallback = function(entry) {
-                // delete directory
-				var deleteDirectory = function(directory) {
-                    entry.removeRecursively(testRemove, that.fail);  
-                }; 
-                // create a sub-directory within directory
-                entry.getDirectory(subDirName, {create: true}, deleteDirectory, that.fail);
-				},
-				testRemove = function() {
-					// test that removed directory no longer exists
-					that.root.getDirectory(dirName, {create:false}, null, testDirExists);
-				},
-				testDirExists = function(error){
-					ok(typeof error !== 'undefined' && error !== null, "removed directory should not exist");
-					equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-					QUnit.start();
-				};
-
-        // create a new directory entry to kick off test
-        this.root.getDirectory(dirName, {create:true}, entryCallback, this.fail);
-    });
-    test("DirectoryEntry.createReader: create reader on existing directory", function() {
-        expect(2);
-        
-        // create reader for root directory 
-        var reader = this.root.createReader();
-        ok(typeof reader !== 'undefined' && reader !== null, "reader object should not be null");
-        ok(typeof reader.readEntries === 'function', "reader object should have a 'readEntries' method");
-    });
-    module('DirectoryReader interface', {
-        // setup function will run before each test
-        setup: function() {
-            this.root = getFileSystemRoot();
-            this.fail = function(error) {
-                console.log('file error: ' + error.code);
-            };   
-        }
-    });
-    test("DirectoryReader.readEntries: read contents of existing directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-        
-        var reader,
-		 testEntries = function(entries) {
-                ok(typeof entries !== 'undefined' && entries !== null, "directory entries should not be null");
-                ok(entries.constructor === Array, "readEntries should return an array of entries");
-                QUnit.start();
-            };
-                
-        // create reader for root directory 
-        reader = this.root.createReader();
-        ok(typeof reader !== 'undefined' && reader !== null, "reader object should not be null");
-        ok(typeof reader.readEntries === 'function', "reader object should have a 'readEntries' method");
-        
-        // read entries
-        reader.readEntries(testEntries, this.fail);
-    });
-    test("DirectoryReader.readEntries: read contents of directory that has been removed", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-        
-        var dirName = "de.createReader.notfound",
-            dirPath = this.root.fullPath + '/' + dirName,
-            that = this,
-            entryCallback = function(directory) {
-                // read entries
-                var readEntries = function() {
-                    var reader = directory.createReader();
-                    reader.readEntries(null, testReader);
-                };
-                // delete directory
-                directory.removeRecursively(readEntries, that.fail);  
-            },
-            testReader = function(error) {
-				var testDirectoryExists = function(error) {
-					ok(typeof error !== 'undefined' && error !== null, "reading entries on a directory that does not exist is an error")
-					equal(error.code, FileError.NOT_FOUND_ERR, "removed directory should not exist");
-					QUnit.start();
-				};
-                ok(typeof error !== 'undefined' && error !== null, "reading entries on a directory that does not exist is an error")
-                equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-				that.root.getDirectory(dirName, {create:false}, null, testDirectoryExists);
-            };
-
-        // create a new directory entry to kick off test
-        this.root.getDirectory(dirName, {create:true}, entryCallback, this.fail);
-    });
-    test("DirectoryEntry.removeRecursively on root file system", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var testRemove = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "removing root file system should generate an error");
-                equal(error.code, FileError.NO_MODIFICATION_ALLOWED_ERR, "error code should be FileError.NO_MODIFICATION_ALLOWED_ERR");
-                QUnit.start();
-            };
-
-        // remove root file system
-        this.root.removeRecursively(null, testRemove);
-    });
-    module('File interface');
-    test("File constructor should be defined", function() {
-        expect(1);
-        ok(typeof File === 'function', "File constructor should be a function.");
-    });
-    test("File attributes should be defined", function() {
-        expect(5);
-        var file = new File();
-        ok(typeof file.name !== 'undefined', "File object should have a 'name' attribute");
-        ok(typeof file.fullPath !== 'undefined', "File object should have a 'fullPath' attribute");
-        ok(typeof file.type !== 'undefined', "File object should have a 'type' attribute");
-        ok(typeof file.lastModifiedDate !== 'undefined', "File object should have a 'lastModifiedDate' attribute");
-        ok(typeof file.size !== 'undefined', "File object should have a 'size' attribute");
-    });
-    module('FileEntry interface', {
-        // setup function will run before each test
-        setup: function() {
-            this.root = getFileSystemRoot();
-            this.fail = function(error) {
-                console.log('file error: ' + error.code);
-            };   
-        }
-    });
-    test("FileEntry methods should be defined", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(3);
-        
-        var fileName = "fe.methods",
-            that = this,
-            testFileEntry = function(fileEntry) {
-                ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "FileEntry should not be null");
-                ok(typeof fileEntry.createWriter === 'function', "FileEntry should have a 'createWriter' method");
-                ok(typeof fileEntry.file === 'function', "FileEntry should have a 'file' method");
-                
-                // cleanup 
-                fileEntry.remove(null, that.fail);
-                QUnit.start();
-            };
-                
-        // create a new file entry to kick off test
-        this.root.getFile(fileName, {create:true}, testFileEntry, this.fail);
-    });
-    test("FileEntry.createWriter should return a FileWriter object", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var fileName = "fe.createWriter",
-            that = this,
-            testFile,
-            entryCallback = function(fileEntry) {
-                testFile = fileEntry;
-                fileEntry.createWriter(testWriter, that.fail);
-            },
-            testWriter = function(writer) {
-                ok(typeof writer !== 'undefined' && writer !== null, "FileWriter object should not be null");
-                ok(writer.constructor === FileWriter, "writer should be a FileWriter object");
-                
-                // cleanup 
-                testFile.remove(null, that.fail);
-                QUnit.start();                
-            };
-                
-        // create a new file entry to kick off test
-        this.root.getFile(fileName, {create:true}, entryCallback, this.fail);
-    });
-    test("FileEntry.file should return a File object", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var fileName = "fe.file",
-            that = this,
-            newFile,
-            entryCallback = function(fileEntry) {
-                newFile = fileEntry;
-                fileEntry.file(testFile, that.fail);
-            },
-            testFile = function(file) {
-                ok(typeof file !== 'undefined' && file !== null, "File object should not be null");
-                ok(file.constructor === File, "File object should be a File");
-                
-                // cleanup 
-                newFile.remove(null, that.fail);
-                QUnit.start();                
-            };
-                
-        // create a new file entry to kick off test
-        this.root.getFile(fileName, {create:true}, entryCallback, this.fail);
-    });
-    test("FileEntry.file: on File that has been removed", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var fileName = "fe.no.file",
-            that = this,
-            entryCallback = function(fileEntry) {
-                // create File object
-                var getFile = function() {
-                    fileEntry.file(null, testFile);
-                };
-                // delete file
-                fileEntry.remove(getFile, that.fail);
-            },
-            testFile = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "invoking FileEntry.file on a file that does not exist is an error");
-                equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-                QUnit.start();                
-            };
-                
-        // create a new file entry to kick off test
-        this.root.getFile(fileName, {create:true}, entryCallback, this.fail);
-    });
-    module('Entry interface', {
-        // setup function will run before each test
-        setup: function() {
-            var that = this;
-            this.root = getFileSystemRoot();
-            this.fail = function(error) {
-                console.log('file error: ' + error.code);
-            };
-			this.unexpectedSuccess = function() {
-				console.log('!!! success function called when not expected !!!');
-			};
-            // deletes specified file or directory
-            this.deleteEntry = function(name, success, error) {
-                // deletes entry, if it exists
-                window.resolveLocalFileSystemURI(that.root.toURI() + '/' + name, 
-                        function(entry) {
-                            console.log('Deleting: ' + entry.fullPath);
-                            if (entry.isDirectory === true) {
-                                entry.removeRecursively(success, error); 
-                            }
-                            else {
-                                entry.remove(success, error);
-                            }
-                        }, 
-                        // doesn't exist
-                        success);
-            };
-            // deletes and re-creates the specified file
-            this.createFile = function(fileName, success, error) {
-                that.deleteEntry(fileName, function() {
-                    console.log('Creating file: ' + that.root.fullPath + '/' + fileName);
-                    that.root.getFile(fileName, {create: true}, success, error);                
-                }, error);
-            };
-            // deletes and re-creates the specified directory
-            this.createDirectory = function(dirName, success, error) {
-                that.deleteEntry(dirName, function() {
-                   console.log('Creating directory: ' + that.root.fullPath + '/' + dirName);
-                   that.root.getDirectory(dirName, {create: true}, success, error); 
-                }, error);
-            };
-        }
-    });
-    test("Entry object", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(13);
-
-        var fileName = "entry",
-            that = this,
-            fullPath = this.root.fullPath + '/' + fileName,
-            testEntry = function(entry) {
-                ok(typeof entry !== 'undefined' && entry !== null, "entry should not be null.");
-                equal(entry.isFile, true, "entry.isFile should be true");
-                equal(entry.isDirectory, false, "entry.isDirectory should be false");
-                equal(entry.name, fileName, "entry object 'name' property should be set");
-                equal(entry.fullPath, fullPath, "entry object 'fullPath' property should be set");
-                ok(typeof entry.getMetadata === 'function', "entry object should have a 'getMetadata' function.");
-                ok(typeof entry.moveTo === 'function', "entry object should have a 'moveTo' function.");
-                ok(typeof entry.copyTo === 'function', "entry object should have a 'copyTo' function.");
-                ok(typeof entry.toURI === 'function', "entry object should have a 'toURI' function.");
-                ok(typeof entry.remove === 'function', "entry object should have a 'remove' function.");
-                ok(typeof entry.getParent === 'function', "entry object should have a 'getParent' function.");
-                ok(typeof entry.createWriter === 'function', "entry object should have a 'createWriter' function.");
-                ok(typeof entry.file === 'function', "entry object should have a 'file' function.");
-                
-                // cleanup
-                that.deleteEntry(fileName);
-                QUnit.start();
-            };
-
-        // create a new file entry
-        this.createFile(fileName, testEntry, this.fail);
-    });
-    test("Entry.getMetadata on file", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var fileName = "entry.metadata.file",
-            that = this,
-            entryCallback = function(entry) {
-                entry.getMetadata(testMetadata, this.fail);
-            },
-            testMetadata = function(metadata) {
-                ok(typeof metadata !== 'undefined' && metadata !== null, "metadata should not be null.");
-                ok(metadata.modificationTime instanceof Date, "metadata.modificationTime should be Date object");
-
-                // cleanup
-                that.deleteEntry(fileName);
-                QUnit.start();
-            };
-        
-        // create a new file entry
-        this.createFile(fileName, entryCallback, this.fail);
-    });
-    test("Entry.getMetadata on directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var dirName = "entry.metadata.dir",
-            that = this,
-            entryCallback = function(entry) {
-                entry.getMetadata(testMetadata, this.fail);
-            },
-            testMetadata = function(metadata) {
-                ok(typeof metadata !== 'undefined' && metadata !== null, "metadata should not be null.");
-                ok(metadata.modificationTime instanceof Date, "metadata.modificationTime should be Date object");
-
-                // cleanup
-                that.deleteEntry(dirName);
-                QUnit.start();
-            };
-        
-        // create a new directory entry
-        this.createDirectory(dirName, entryCallback, this.fail);
-    });
-    test("Entry.getParent on file in root file system", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var fileName = "entry.parent.file",
-            that = this,
-            rootPath = this.root.fullPath,
-            entryCallback = function(entry) {
-                entry.getParent(testParent, this.fail);
-            },
-            testParent = function(parent) {
-                ok(typeof parent !== 'undefined' && parent !== null, "parent directory should not be null.");
-                equal(parent.fullPath, rootPath, "parent fullPath should be root file system");
-
-                // cleanup
-                that.deleteEntry(fileName);
-                QUnit.start();
-            };
-    
-        // create a new file entry
-        this.createFile(fileName, entryCallback, this.fail);
-    });
-    test("Entry.getParent on directory in root file system", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var dirName = "entry.parent.dir",
-            that = this,
-            rootPath = this.root.fullPath,
-            entryCallback = function(entry) {
-                entry.getParent(testParent, this.fail);
-            },
-            testParent = function(parent) {
-                ok(typeof parent !== 'undefined' && parent !== null, "parent directory should not be null.");
-                equal(parent.fullPath, rootPath, "parent fullPath should be root file system");
-
-                // cleanup
-                that.deleteEntry(dirName);
-                QUnit.start();
-            };
-
-        // create a new directory entry
-        this.createDirectory(dirName, entryCallback, this.fail);
-    });
-    test("Entry.getParent on root file system", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var rootPath = this.root.fullPath,
-		 testParent = function(parent) {
-                ok(typeof parent !== 'undefined' && parent !== null, "parent directory should not be null.");
-                equal(parent.fullPath, rootPath, "parent fullPath should be root file system");
-                QUnit.start();
-            };
-
-        // create a new directory entry
-        this.root.getParent(testParent, this.fail);
-    });
-    test("Entry.toURI on file", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var fileName = "entry.uri.file",
-            that = this,
-            rootPath = this.root.fullPath,
-            testURI = function(entry) {
-                var uri = entry.toURI();
-                ok(typeof uri !== 'undefined' && uri !== null, "URI should not be null.");
-                ok(uri.indexOf(rootPath) !== -1, "URI should contain root file system path");
-
-                // cleanup
-                that.deleteEntry(fileName);
-                QUnit.start();
-            };
-    
-        // create a new file entry
-        this.createFile(fileName, testURI, this.fail);
-    });
-    test("Entry.toURI on directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var dirName = "entry.uri.dir",
-            that = this,
-            rootPath = this.root.fullPath,
-            testURI = function(entry) {
-                var uri = entry.toURI();
-                ok(typeof uri !== 'undefined' && uri !== null, "URI should not be null.");
-                ok(uri.indexOf(rootPath) !== -1, "URI should contain root file system path");
-
-                // cleanup
-                that.deleteEntry(dirName);
-                QUnit.start();
-            };
-
-        // create a new directory entry
-        this.createDirectory(dirName, testURI, this.fail);
-    });
-    test("Entry.remove on file", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(3);
-        
-        var fileName = "entry.rm.file",
-            that = this,
-            fullPath = this.root.fullPath + '/' + fileName,
-		 entryCallback = function(entry) {
-				var checkRemove = function() {
-					that.root.getFile(fileName, null, that.unexpectedSuccess, testRemove);  
-				};
-                ok(typeof entry !== 'undefined' && entry !== null, "entry should not be null.");
-                entry.remove(checkRemove, that.fail);
-            },
-			testRemove = function(error) {
-				ok(typeof error !== 'undefined' && error !== null, "file should not exist");
-				equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR"); 
-                // cleanup
-                that.deleteEntry(fileName);
-                QUnit.start();
-            };
-    
-        // create a new file entry
-        this.createFile(fileName, entryCallback, this.fail);
-    });
-    test("Entry.remove on empty directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(3);
-        
-        var dirName = "entry.rm.dir",
-            that = this,
-            fullPath = this.root.fullPath + '/' + dirName,
-            entryCallback = function(entry) {
-				var checkRemove = function() {
-					that.root.getDirectory(dirName, null, that.unexpectedSuccess, testRemove);  
-				};
-                ok(typeof entry !== 'undefined' && entry !== null, "entry should not be null.");
-                entry.remove(checkRemove, that.fail);
-            },
-            testRemove = function(error) {
-				ok(typeof error !== 'undefined' && error !== null, "directory should not exist");
-				equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR"); 
-                // cleanup
-                that.deleteEntry(dirName);                
-                QUnit.start();
-            };
-
-        // create a new directory entry
-        this.createDirectory(dirName, entryCallback, this.fail);
-    });
-    test("Entry.remove on non-empty directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-        
-        var dirName = "entry.rm.dir.not.empty",
-            that = this,
-            fullPath = this.root.fullPath + '/' + dirName,
-            fileName = "remove.txt",
-            entryCallback = function(entry) {
-				var checkFile = function(error) {
-					ok(typeof error !== 'undefined' && error !== null, "removing non-empty directory should generate an error");
-					equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-					// verify that dir still exists
-					that.root.getDirectory(dirName, null, testRemove, that.fail);  
-				};
-                // delete directory
-                var deleteDirectory = function(fileEntry) {
-                    entry.remove(that.unexpectedSuccess, checkFile);  
-                }; 
-                // create a file within directory, then try to delete directory
-                entry.getFile(fileName, {create: true}, deleteDirectory, that.fail);
-            },
-			testRemove = function(entry) {
-				ok(typeof entry !== 'undefined' && entry !== null, "entry should not be null.");
-				equal(entry.fullPath, fullPath, "dir entry should still exisit");
-                // cleanup
-                that.deleteEntry(dirName);
-                QUnit.start();
-            };
-
-        // create a new directory entry
-        this.createDirectory(dirName, entryCallback, this.fail);
-    });
-    test("Entry.remove on root file system", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var testRemove = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "removing root file system should generate an error");
-                equal(error.code, FileError.NO_MODIFICATION_ALLOWED_ERR, "error code should be FileError.NO_MODIFICATION_ALLOWED_ERR");
-                QUnit.start();
-            };
-
-        // remove entry that doesn't exist
-        this.root.remove(null, testRemove);
-    });
-    test("Entry.copyTo: file", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(10);
-        
-        var file1 = "entry.copy.file1",
-            file2 = "entry.copy.file2",
-            that = this,
-            fullPath = this.root.fullPath + '/' + file2,
-            entryCallback = function(entry) {
-                // copy file1 to file2
-                entry.copyTo(that.root, file2, testCopy, that.fail);
-            },
-			testCopy = function(entry) {
-				
-				ok(typeof entry !== 'undefined' && entry !== null, "copied file entry should not be null");
-				equals(entry.isFile, true, "entry 'isFile' attribute should be set to true");
-				equals(entry.isDirectory, false, "entry 'isDirectory' attribute should be set to false");
-				equals(entry.fullPath, fullPath, "entry 'fullPath' should be set correctly");
-				equals(entry.name, file2, "entry 'name' attribute should be set correctly");
-				that.root.getFile(file2, {create:false}, testFileExists, null);							  
-                
-            },
-			testFileExists = function(entry2) {
-				// a bit redundant since copy returned this entry already
-				ok(typeof entry2 !== 'undefined' && entry2 !== null, "copied file entry should not be null");
-				equals(entry2.isFile, true, "entry 'isFile' attribute should be set to true");
-				equals(entry2.isDirectory, false, "entry 'isDirectory' attribute should be set to false");
-				equals(entry2.fullPath, fullPath, "entry 'fullPath' should be set correctly");
-				equals(entry2.name, file2, "entry 'name' attribute should be set correctly");
-		 
-				// cleanup
-				that.deleteEntry(file1);
-				that.deleteEntry(file2);
-				QUnit.start();
-			};
-
-        // create a new file entry to kick off test
-        this.createFile(file1, entryCallback, this.fail);
-    });
-    test("Entry.copyTo: file onto itself", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var file1 = "entry.copy.fos.file1",
-            that = this,
-            entryCallback = function(entry) {
-                // copy file1 onto itself
-                entry.copyTo(that.root, null, null, testCopy);
-            },
-		 testCopy = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "it is an error to copy an entry into its parent if a different name is not specified");
-                equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-
-                // cleanup
-                that.deleteEntry(file1);
-                QUnit.start();
-            };
-
-        // create a new file entry to kick off test
-        this.createFile(file1, entryCallback, this.fail);
-    });
-    test("Entry.copyTo: directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(15);
-        
-        var file1 = "file1",
-            srcDir = "entry.copy.srcDir",
-            dstDir = "entry.copy.dstDir",
-            dstPath = this.root.fullPath + '/' + dstDir,
-            filePath = dstPath + '/' + file1,
-            that = this,
-            entryCallback = function(directory) {
-                var copyDir = function(fileEntry) {
-                    // copy srcDir to dstDir
-                    directory.copyTo(that.root, dstDir, testCopy, that.fail);                    
-                };
-              // create a file within new directory
-              directory.getFile(file1, {create: true}, copyDir, that.fail);
-            },
-            testCopy = function(directory) {
-				
-                ok(typeof directory !== 'undefined' && directory !== null, "copied directory entry should not be null");
-                equals(directory.isFile, false, "entry 'isFile' attribute should be false");
-                equals(directory.isDirectory, true, "entry 'isDirectory' attribute should be true");
-                equals(directory.fullPath, dstPath, "entry 'fullPath' should be set correctly");
-                equals(directory.name, dstDir, "entry 'name' attribute should be set correctly");
-		 
-				that.root.getDirectory(dstDir, {create:false}, testDirExists, that.fail);
-		   },
-			testDirExists = function(dirEntry) {
-				 ok(typeof dirEntry !== 'undefined' && dirEntry !== null, "copied directory entry should not be null");
-				 equals(dirEntry.isFile, false, "entry 'isFile' attribute should be false");
-				 equals(dirEntry.isDirectory, true, "entry 'isDirectory' attribute should be true");
-				 equals(dirEntry.fullPath, dstPath, "entry 'fullPath' should be set correctly");
-				 equals(dirEntry.name, dstDir, "entry 'name' attribute should be set correctly");
-				 
-				 dirEntry.getFile(file1, {create:false}, testFileExists, that.fail);
-		 
-		 };
-			testFileExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "copied directory entry should not be null");
-				equals(fileEntry.isFile, true, "entry 'isFile' attribute should be true");
-				equals(fileEntry.isDirectory, false, "entry 'isDirectory' attribute should be false");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-				equals(fileEntry.name, file1, "entry 'name' attribute should be set correctly");
-                
-
-                // cleanup
-                that.deleteEntry(srcDir);
-                that.deleteEntry(dstDir);
-                QUnit.start();
-            };
-
-        // create a new directory entry to kick off test
-        this.createDirectory(srcDir, entryCallback, this.fail);
-    });
-    test("Entry.copyTo: directory onto itself", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(6);
-        
-        var file1 = "file1",
-            srcDir = "entry.copy.dos.srcDir",
-            srcPath = this.root.fullPath + '/' + srcDir,
-            filePath = srcPath + '/' + file1,
-            that = this,
-            entryCallback = function(directory) {
-                var copyDir = function(fileEntry) {
-                    // copy srcDir onto itself
-                    directory.copyTo(that.root, null, null, testCopy);                    
-                };
-              // create a file within new directory
-              directory.getFile(file1, {create: true}, copyDir, that.fail);
-            },
-            testCopy = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "it is an error to copy an entry into its parent if a different name is not specified");
-                equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-                
-				that.root.getDirectory(srcDir, {create:false}, testDirectoryExists, null);
-			},
-			 testDirectoryExists = function(dirEntry) {
-				// returning confirms existence so just check fullPath entry
-				ok(typeof dirEntry !== 'undefined' && dirEntry !== null, "original directory should exist.");
-				equals(dirEntry.fullPath, srcPath, "entry 'fullPath' should be set correctly");
-			 
-				dirEntry.getFile(file1, {create:false}, testFileExists, null);
-			 },
-			testFileExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "original directory contents should exist.");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-                
-                // cleanup
-                that.deleteEntry(srcDir);
-                QUnit.start();
-            };
-
-        // create a new directory entry to kick off test
-        this.createDirectory(srcDir, entryCallback, this.fail);
-    });
-    test("Entry.copyTo: directory into itself", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-        
-        var srcDir = "entry.copy.dis.srcDir",
-            dstDir = "entry.copy.dis.dstDir",
-            srcPath = this.root.fullPath + '/' + srcDir,
-            that = this,
-            entryCallback = function(directory) {
-                // copy source directory into itself
-                directory.copyTo(directory, dstDir, null, testCopy);                    
-            },
-            testCopy = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "it is an error to copy a directory into itself");
-                equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-                
-				that.root.getDirectory(srcDir, {create:false}, testDirectoryExists, null);
-			},
-			testDirectoryExists = function(dirEntry) {
-				// returning confirms existence so just check fullPath entry
-				ok(typeof dirEntry !== 'undefined' && dirEntry !== null, "original directory should exist.");
-				equals(dirEntry.fullPath, srcPath, "entry 'fullPath' should be set correctly");
-		 
-                // cleanup
-                that.deleteEntry(srcDir);
-                QUnit.start();
-            };
-
-        // create a new directory entry to kick off test
-        this.createDirectory(srcDir, entryCallback, this.fail);
-    });
-    test("Entry.copyTo: directory that does not exist", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-        
-        var file1 = "entry.copy.dnf.file1", 
-            dstDir = "entry.copy.dnf.dstDir",
-            filePath = this.root.fullPath + '/' + file1,
-            dstPath = this.root.fullPath + '/' + dstDir,
-            that = this,
-            entryCallback = function(entry) {
-                // copy file to target directory that does not exist
-                directory = new DirectoryEntry();
-				directory.fullPath = dstPath;
-                entry.copyTo(directory, null, null, testCopy);                 
-            },
-            testCopy = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "it is an error to copy to a directory that does not exist");
-                equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-				that.root.getFile(file1, {create: false}, testFileExists, null);
-			},
-			testFileExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "original file should exist");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-		 
-                // cleanup
-                that.deleteEntry(file1);
-                QUnit.start();
-            };
-
-        // create a new file entry to kick off test
-        this.createFile(file1, entryCallback, this.fail);
-    });
-    test("Entry.copyTo: invalid target name", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var file1 = "entry.copy.itn.file1",
-            file2 = "bad:file:name",
-            that = this,
-            filePath = this.root.fullPath + '/' + file1,
-            entryCallback = function(entry) {
-                // copy file1 to file2
-                entry.copyTo(that.root, file2, null, testCopy);
-            },
-            testCopy = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "invalid file name should result in error");
-                equal(error.code, FileError.ENCODING_ERR, "error code should be FileError.ENCODING_ERR");
-
-                // cleanup
-                that.deleteEntry(file1);
-                QUnit.start();
-            };
-
-        // create a new file entry
-        this.createFile(file1, entryCallback, this.fail);
-    });
-    test("Entry.moveTo: file to same parent", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(9);
-        
-        var file1 = "entry.move.fsp.file1",
-            file2 = "entry.move.fsp.file2",
-            that = this,
-            srcPath = this.root.fullPath + '/' + file1,
-            dstPath = this.root.fullPath + '/' + file2,
-            entryCallback = function(entry) {
-                // move file1 to file2
-                entry.moveTo(that.root, file2, testMove, that.fail);
-            },
-            testMove = function(entry) {
-                ok(typeof entry !== 'undefined' && entry !== null, "file entry should not be null");
-                equals(entry.isFile, true, "entry 'isFile' attribute should be set to true");
-                equals(entry.isDirectory, false, "entry 'isDirectory' attribute should be set to false");
-                equals(entry.fullPath, dstPath, "entry 'fullPath' should be set correctly");
-                equals(entry.name, file2, "entry 'name' attribute should be set correctly");
-		 
-				that.root.getFile(file2, {create:false}, testMovedExists, null);
-			},
-			testMovedExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "moved file should exist");
-				equals(fileEntry.fullPath, dstPath, "entry 'fullPath' should be set correctly");
-               
-				that.root.getFile(file1, {create:false}, null, testOrig);
-			},
-			testOrig = function(error) {
-                //ok(navigator.fileMgr.testFileExists(srcPath) === false, "original file should not exist.");
-				ok(typeof error !== 'undefined' && error !== null, "it is an error if original file exists after a move");
-				equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-		 
-		 
-                // cleanup
-                that.deleteEntry(file1);
-                that.deleteEntry(file2);
-                QUnit.start();
-            };
-
-        // create a new file entry to kick off test
-        this.createFile(file1, entryCallback, this.fail);
-    });
-    test("Entry.moveTo: file to new parent", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(9);
-        
-        var file1 = "entry.move.fnp.file1",
-            dir = "entry.move.fnp.dir",
-            that = this,
-            srcPath = this.root.fullPath + '/' + file1,
-            dstPath = this.root.fullPath + '/' + dir + '/' + file1,
-            entryCallback = function(entry) {
-                // move file1 to new directory
-                var moveFile = function(directory) {
-					
-					var testMove = function(entry) {
-						ok(typeof entry !== 'undefined' && entry !== null, "file entry should not be null");
-						equals(entry.isFile, true, "entry 'isFile' attribute should be set to true");
-						equals(entry.isDirectory, false, "entry 'isDirectory' attribute should be set to false");
-						equals(entry.fullPath, dstPath, "entry 'fullPath' should be set correctly");
-						equals(entry.name, file1, "entry 'name' attribute should be set correctly");
-						// test the moved file exists
-						directory.getFile(file1, {create:false}, testMovedExists, null);
-					};
-					// move the file
-					entry.moveTo(directory, null, testMove, that.fail);
-				};
-		 
-                // create a parent directory to move file to
-                that.root.getDirectory(dir, {create: true}, moveFile, that.fail);
-            },
-			testMovedExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "moved file should exist");
-				equals(fileEntry.fullPath, dstPath, "entry 'fullPath' should be set correctly");
-		 
-				that.root.getFile(file1, {create:false}, null, testOrig);
-			},
-			testOrig = function(error) {
-				ok(typeof error !== 'undefined' && error !== null, "it is an error if original file exists after a move");
-				equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-				
-				// cleanup
-                that.deleteEntry(file1);
-                that.deleteEntry(dir);
-                QUnit.start();
-            };
-
-        // ensure destination directory is cleaned up before test
-        this.deleteEntry(dir, function() {
-            // create a new file entry to kick off test
-            that.createFile(file1, entryCallback, that.fail);            
-        }, this.fail);
-    });
-    test("Entry.moveTo: directory to same parent", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(9);
-        
-        var file1 = "file1",
-            srcDir = "entry.move.dsp.srcDir",
-            dstDir = "entry.move.dsp.dstDir",
-            srcPath = this.root.fullPath + '/' + srcDir,
-            dstPath = this.root.fullPath + '/' + dstDir,
-            filePath = dstPath + '/' + file1,
-            that = this,
-            entryCallback = function(directory) {
-                var moveDir = function(fileEntry) {
-                    // move srcDir to dstDir
-                    directory.moveTo(that.root, dstDir, testMove, that.fail);                    
-                };
-              // create a file within directory
-              directory.getFile(file1, {create: true}, moveDir, that.fail);
-            },
-            testMove = function(directory) {
-                ok(typeof directory !== 'undefined' && directory !== null, "new directory entry should not be null");
-                equals(directory.isFile, false, "entry 'isFile' attribute should be false");
-                equals(directory.isDirectory, true, "entry 'isDirectory' attribute should be true");
-                equals(directory.fullPath, dstPath, "entry 'fullPath' should be set correctly");
-                equals(directory.name, dstDir, "entry 'name' attribute should be set correctly");
-				// test that moved file exists in destination dir
-				directory.getFile(file1, {create:false}, testMovedExists, null);
-			},
-			testMovedExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "moved file should exist within moved directory");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-				// test that the moved file no longer exists in original dir
-				that.root.getFile(file1, {create:false}, null, testOrig);
-			},
-			testOrig = function(error) {
-				ok(typeof error !== 'undefined' && error !== null, "it is an error if original file exists after a move");
-				equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-		 
-				// cleanup
-                that.deleteEntry(srcDir);
-                that.deleteEntry(dstDir);
-                QUnit.start();
-            };
-
-        // ensure destination directory is cleaned up before test
-        this.deleteEntry(dstDir, function() {
-            // create a new directory entry to kick off test
-            that.createDirectory(srcDir, entryCallback, that.fail);
-        }, this.fail);
-    });
-    test("Entry.moveTo: directory to new parent", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(9);
-        
-        var file1 = "file1",
-            srcDir = "entry.move.dnp.srcDir",
-            dstDir = "entry.move.dnp.dstDir",
-            srcPath = this.root.fullPath + '/' + srcDir,
-            dstPath = this.root.fullPath + '/' + dstDir,
-            filePath = dstPath + '/' + file1,
-            that = this,
-            entryCallback = function(directory) {
-                var moveDir = function(fileEntry) {
-                    // move srcDir to dstDir
-                    directory.moveTo(that.root, dstDir, testMove, that.fail);                    
-                };
-              // create a file within directory
-              directory.getFile(file1, {create: true}, moveDir, that.fail);
-            },
-            testMove = function(directory) {
-                ok(typeof directory !== 'undefined' && directory !== null, "new directory entry should not be null");
-                equals(directory.isFile, false, "entry 'isFile' attribute should be false");
-                equals(directory.isDirectory, true, "entry 'isDirectory' attribute should be true");
-                equals(directory.fullPath, dstPath, "entry 'fullPath' should be set correctly");
-                equals(directory.name, dstDir, "entry 'name' attribute should be set correctly");
-				// test that moved file exists in destination dir
-				directory.getFile(file1, {create:false}, testMovedExists, null);
-			},
-			testMovedExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "moved file should exist within moved directory");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-				// test that the moved file no longer exists in original dir
-				that.root.getFile(file1, {create:false}, null, testOrig);
-			},
-			testOrig = function(error) {
-				ok(typeof error !== 'undefined' && error !== null, "it is an error if original file exists after a move");
-				equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-				
-				// cleanup
-                that.deleteEntry(srcDir);
-                that.deleteEntry(dstDir);
-                QUnit.start();
-            };
-
-        // ensure destination directory is cleaned up before test
-        this.deleteEntry(dstDir, function() {
-            // create a new directory entry to kick off test
-            that.createDirectory(srcDir, entryCallback, that.fail);
-        }, this.fail);
-    });
-    test("Entry.moveTo: directory onto itself", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(6);
-        
-        var file1 = "file1",
-            srcDir = "entry.move.dos.srcDir",
-            srcPath = this.root.fullPath + '/' + srcDir,
-            filePath = srcPath + '/' + file1,
-            that = this,
-            entryCallback = function(directory) {
-                var moveDir = function(fileEntry) {
-                    // move srcDir onto itself
-                    directory.moveTo(that.root, null, null, testMove);                    
-                };
-              // create a file within new directory
-              directory.getFile(file1, {create: true}, moveDir, that.fail);
-            },
-            testMove = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "it is an error to move an entry into its parent if a different name is not specified");
-                equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-                
-				// test that original dir still exists
-				that.root.getDirectory(srcDir, {create:false}, testDirectoryExists, null);
-			},
-			testDirectoryExists = function(dirEntry) {
-				// returning confirms existence so just check fullPath entry
-				ok(typeof dirEntry !== 'undefined' && dirEntry !== null, "original directory should exist.");
-				equals(dirEntry.fullPath, srcPath, "entry 'fullPath' should be set correctly");
-		 
-				dirEntry.getFile(file1, {create:false}, testFileExists, null);
-			},
-			testFileExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "original directory contents should exist.");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-						
-				// cleanup
-                that.deleteEntry(srcDir);
-                QUnit.start();
-            };
-
-        // create a new directory entry to kick off test
-        this.createDirectory(srcDir, entryCallback, this.fail);
-    });
-    test("Entry.moveTo: directory into itself", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-        
-        var srcDir = "entry.move.dis.srcDir",
-            dstDir = "entry.move.dis.dstDir",
-            srcPath = this.root.fullPath + '/' + srcDir,
-            that = this,
-            entryCallback = function(directory) {
-                // move source directory into itself
-                directory.moveTo(directory, dstDir, null, testMove);                    
-            },
-            testMove = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "it is an error to move a directory into itself");
-                equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-				// make sure original directory still exists
-				that.root.getDirectory(srcDir, {create:false}, testDirectoryExists, null);
-			},
-			testDirectoryExists = function(entry) {
-				ok(typeof entry !== 'undefined' && entry !== null, "original directory should exist.");
-				equals(entry.fullPath, srcPath, "entry 'fullPath' should be set correctly");
-		 
-				// cleanup
-                that.deleteEntry(srcDir);
-                QUnit.start();
-            };
-
-        // create a new directory entry to kick off test
-        this.createDirectory(srcDir, entryCallback, this.fail);
-    });
-    test("Entry.moveTo: file onto itself", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-        
-        var file1 = "entry.move.fos.file1",
-            filePath = this.root.fullPath + '/' + file1,
-            that = this,
-            entryCallback = function(entry) {
-                // move file1 onto itself
-                entry.moveTo(that.root, null, null, testMove);
-            },
-            testMove = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "it is an error to move an entry into its parent if a different name is not specified");
-                equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-                
-				//test that original file still exists
-				that.root.getFile(file1, {create:false}, testFileExists, null);
-			},
-			testFileExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "original directory contents should exist.");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-		 
-                // cleanup
-                that.deleteEntry(file1);
-                QUnit.start();
-            };
-
-        // create a new file entry to kick off test
-        this.createFile(file1, entryCallback, this.fail);
-    });
-    test("Entry.moveTo: file onto existing directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(6);
-        
-        var file1 = "entry.move.fod.file1",
-            dstDir = "entry.move.fod.dstDir",
-            subDir = "subDir",
-            dirPath = this.root.fullPath + '/' + dstDir + '/' + subDir,
-            filePath = this.root.fullPath + '/' + file1,
-            that = this,
-            entryCallback = function(entry) {
-                var createSubDirectory = function(directory) {
-                    var moveFile = function(subDirectory) {
-						var testMove = function(error) {
-							ok(typeof error !== 'undefined' && error !== null, "it is an error to move a file onto an existing directory");
-							equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-							// test that original dir still exists
-							directory.getDirectory(subDir, {create:false}, testDirectoryExists, null);
-						};
-                        // move file1 onto sub-directory
-                        entry.moveTo(directory, subDir, null, testMove);                    
-                    };
-                    // create sub-directory 
-                    directory.getDirectory(subDir, {create: true}, moveFile, that.fail);                    
-                };
-                // create top level directory 
-                that.root.getDirectory(dstDir, {create: true}, createSubDirectory, that.fail);
-            },
-			testDirectoryExists = function(dirEntry) {
-				ok(typeof dirEntry !== 'undefined' && dirEntry !== null, "original directory contents should exist.");
-				equals(dirEntry.fullPath, dirPath, "entry 'fullPath' should be set correctly");
-				// test that original file still exists
-				that.root.getFile(file1, {create:false},testFileExists, null);
-			},
-			testFileExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "original directory contents should exist.");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-
-                // cleanup
-                that.deleteEntry(file1);
-                that.deleteEntry(dstDir);
-                QUnit.start();
-            };
-
-        // ensure destination directory is cleaned up before test
-        this.deleteEntry(dstDir, function() {
-            // create a new file entry to kick off test
-            that.createFile(file1, entryCallback, that.fail);
-        }, this.fail);
-    });
-    test("Entry.moveTo: directory onto existing file", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(6);
-        
-        var file1 = "entry.move.dof.file1",
-            srcDir = "entry.move.dof.srcDir",
-            dirPath = this.root.fullPath + '/' + srcDir,
-            filePath = this.root.fullPath + '/' + file1,
-            that = this,
-            entryCallback = function(entry) {
-                    var moveDir = function(fileEntry) {
-                        // move directory onto file
-                        entry.moveTo(that.root, file1, null, testMove);                    
-                    };
-                // create file
-                that.root.getFile(file1, {create: true}, moveDir, that.fail);
-            },
-            testMove = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "it is an error to move a directory onto an existing file");
-                equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-                // test that original directory exists
-				that.root.getDirectory(srcDir, {create:false}, testDirectoryExists, null);
-			},
-			testDirectoryExists = function(dirEntry) {
-				// returning confirms existence so just check fullPath entry
-				ok(typeof dirEntry !== 'undefined' && dirEntry !== null, "original directory should exist.");
-				equals(dirEntry.fullPath, dirPath, "entry 'fullPath' should be set correctly");
-				// test that original file exists
-				that.root.getFile(file1, {create:false}, testFileExists, null);
-			},
-			testFileExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "original directory contents should exist.");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-		 
-		 
-                // cleanup
-                that.deleteEntry(file1);
-                that.deleteEntry(srcDir);
-                QUnit.start();
-            };
-
-          // create a new directory entry to kick off test
-          this.createDirectory(srcDir, entryCallback, this.fail);
-    });
-    test("Entry.copyTo: directory onto existing file", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(6);
-        
-        var file1 = "entry.copy.dof.file1",
-            srcDir = "entry.copy.dof.srcDir",
-            dirPath = this.root.fullPath + '/' + srcDir,
-            filePath = this.root.fullPath + '/' + file1,
-            that = this,
-            entryCallback = function(entry) {
-                    var copyDir = function(fileEntry) {
-                        // move directory onto file
-                        entry.copyTo(that.root, file1, null, testMove);                    
-                    };
-                // create file
-                that.root.getFile(file1, {create: true}, copyDir, that.fail);
-            },
-            testMove = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "it is an error to copy a directory onto an existing file");
-                equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-                //test that original dir still exists
-				that.root.getDirectory(srcDir, {create:false}, testDirectoryExists, null);
-			},
-			testDirectoryExists = function(dirEntry) {
-				// returning confirms existence so just check fullPath entry
-				ok(typeof dirEntry !== 'undefined' && dirEntry !== null, "original directory should exist.");
-				equals(dirEntry.fullPath, dirPath, "entry 'fullPath' should be set correctly");
-				// test that original file still exists
-				that.root.getFile(file1, {create:false}, testFileExists, null);
-			},
-			testFileExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "original directory contents should exist.");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-		 
-                // cleanup
-                that.deleteEntry(file1);
-                that.deleteEntry(srcDir);
-                QUnit.start();
-            };
-
-          // create a new directory entry to kick off test
-          this.createDirectory(srcDir, entryCallback, this.fail);
-    });
-    test("Entry.moveTo: directory onto directory that is not empty", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(6);
-        
-        var srcDir = "entry.move.dod.srcDir",
-            dstDir = "entry.move.dod.dstDir",
-            subDir = "subDir",
-            srcPath = this.root.fullPath + '/' + srcDir,
-            dstPath = this.root.fullPath + '/' + dstDir + '/' + subDir,
-            that = this,
-            entryCallback = function(entry) {
-                var createSubDirectory = function(directory) {
-                    var moveDir = function(subDirectory) {
-                        // move srcDir onto dstDir (not empty)
-                        entry.moveTo(that.root, dstDir, null, testMove);                    
-                    };
-					var testMove = function(error) {
-						ok(typeof error !== 'undefined' && error !== null, "it is an error to move a directory onto a directory that is not empty");
-						equal(error.code, FileError.INVALID_MODIFICATION_ERR, "error code should be FileError.INVALID_MODIFICATION_ERR");
-		 
-						// test that destination directory still exists
-						directory.getDirectory(subDir, {create:false}, testDirectoryExists, null);
-					};
-                    // create sub-directory 
-                    directory.getDirectory(subDir, {create: true}, moveDir, that.fail);                    
-                };
-                // create top level directory 
-                that.root.getDirectory(dstDir, {create: true}, createSubDirectory, that.fail);
-            },
-			testDirectoryExists = function(dirEntry) {
-				// returning confirms existence so just check fullPath entry
-				ok(typeof dirEntry !== 'undefined' && dirEntry !== null, "original directory should exist.");
-				equals(dirEntry.fullPath, dstPath, "entry 'fullPath' should be set correctly");
-				// test that source directory exists
-				that.root.getDirectory(srcDir,{create:false}, testSrcDirectoryExists, null);
-			},
-			testSrcDirectoryExists = function(srcEntry){
-				ok(typeof srcEntry !== 'undefined' && srcEntry !== null, "original directory should exist.");
-				equals(srcEntry.fullPath, srcPath, "entry 'fullPath' should be set correctly");
-                // cleanup
-                that.deleteEntry(srcDir);
-                that.deleteEntry(dstDir);
-                QUnit.start();
-            };
-
-        // ensure destination directory is cleaned up before test
-        this.deleteEntry(dstDir, function() {
-            // create a new file entry to kick off test
-            that.createDirectory(srcDir, entryCallback, that.fail);
-        }, this.fail);
-    });
-    test("Entry.moveTo: file replace existing file", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(9);
-        
-        var file1 = "entry.move.frf.file1",
-            file2 = "entry.move.frf.file2",
-            file1Path = this.root.fullPath + '/' + file1,
-            file2Path = this.root.fullPath + '/' + file2,
-            that = this,
-            entryCallback = function(entry) {
-                    var moveFile = function(fileEntry) {
-                        // replace file2 with file1
-                        entry.moveTo(that.root, file2, testMove, that.fail);                    
-                    };
-                // create file
-                that.root.getFile(file2, {create: true}, moveFile, that.fail);
-            },
-		 testMove = function(entry) {
-                ok(typeof entry !== 'undefined' && entry !== null, "file entry should not be null")
-                equals(entry.isFile, true, "entry 'isFile' attribute should be true");
-                equals(entry.isDirectory, false, "entry 'isDirectory' attribute should be false");
-                equals(entry.fullPath, file2Path, "entry 'fullPath' should be set correctly");
-                equals(entry.name, file2, "entry 'name' attribute should be set correctly");
-                
-				// test that old file does not exists
-				that.root.getFile(file1, {create:false}, null, testFileMoved);
-			},
-		 testFileMoved = function(error){
-				ok(typeof error !== 'undefined' && error !== null, "it is an error if original file exists after a move");
-				equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-				// test that new file exists
-				that.root.getFile(file2, {create:false}, testFileExists, null);
-			},
-		 testFileExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "original directory contents should exist.");
-				equals(fileEntry.fullPath, file2Path, "entry 'fullPath' should be set correctly");
-		 
-                // cleanup
-                that.deleteEntry(file1);
-                that.deleteEntry(file2);
-                QUnit.start();
-            };
-
-          // create a new directory entry to kick off test
-          this.createFile(file1, entryCallback, this.fail);
-    });
-    test("Entry.moveTo: directory replace empty directory", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(9);
-        
-        var file1 = "file1",
-            srcDir = "entry.move.drd.srcDir",
-            dstDir = "entry.move.drd.dstDir",
-            srcPath = this.root.fullPath + '/' + srcDir,
-            dstPath = this.root.fullPath + '/' + dstDir,
-            filePath = dstPath + '/' + file1,
-            that = this,
-            entryCallback = function(directory) {
-                var mkdir = function(fileEntry) {
-                    // create destination directory
-                    that.root.getDirectory(dstDir, {create: true}, moveDir, that.fail);
-                };
-                var moveDir = function(fileEntry) {
-                    // move srcDir to dstDir
-                    directory.moveTo(that.root, dstDir, testMove, that.fail);                    
-                };
-              // create a file within source directory
-              directory.getFile(file1, {create: true}, mkdir, that.fail);
-            },
-            testMove = function(directory) {
-                ok(typeof directory !== 'undefined' && directory !== null, "new directory entry should not be null");
-                equals(directory.isFile, false, "entry 'isFile' attribute should be false");
-                equals(directory.isDirectory, true, "entry 'isDirectory' attribute should be true");
-                equals(directory.fullPath, dstPath, "entry 'fullPath' should be set correctly");
-                equals(directory.name, dstDir, "entry 'name' attribute should be set correctly");
-                // test that old directory contents have been moved
-				directory.getFile(file1, {create:false}, testFileExists, null);
-			},
-			testFileExists = function(fileEntry) {
-				ok(typeof fileEntry !== 'undefined' && fileEntry !== null, "original directory contents should exist.");
-				equals(fileEntry.fullPath, filePath, "entry 'fullPath' should be set correctly");
-		 
-                // test that old directory no longer exists
-				that.root.getDirectory(srcDir, {create:false}, null, testRemoved);
-			},
-			testRemoved = function(error){
-				ok(typeof error !== 'undefined' && error !== null, "it is an error if original file exists after a move");
-				equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-                
-                // cleanup
-                that.deleteEntry(srcDir);
-                that.deleteEntry(dstDir);
-                QUnit.start();
-            };
-
-        // ensure destination directory is cleaned up before test
-        this.deleteEntry(dstDir, function() {
-            // create a new directory entry to kick off test
-            that.createDirectory(srcDir, entryCallback, that.fail);
-        }, this.fail);
-    });
-    test("Entry.moveTo: directory that does not exist", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var file1 = "entry.move.dnf.file1", 
-            dstDir = "entry.move.dnf.dstDir",
-            filePath = this.root.fullPath + '/' + file1,
-            dstPath = this.root.fullPath + '/' + dstDir,
-            that = this,
-            entryCallback = function(entry) {
-                // move file to directory that does not exist
-                directory = new DirectoryEntry();
-				directory.fullPath = dstPath;
-                entry.moveTo(directory, null, null, testMove);                 
-            },
-            testMove = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "it is an error to move to a directory that does not exist");
-                equal(error.code, FileError.NOT_FOUND_ERR, "error code should be FileError.NOT_FOUND_ERR");
-				
-				// cleanup
-                that.deleteEntry(file1);
-                QUnit.start();
-            };
-
-        // create a new file entry to kick off test
-        this.createFile(file1, entryCallback, this.fail);
-    });
-    test("Entry.moveTo: invalid target name", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var file1 = "entry.move.itn.file1",
-            file2 = "bad:file:name",
-            that = this,
-            filePath = this.root.fullPath + '/' + file1,
-            entryCallback = function(entry) {
-                // move file1 to file2
-                entry.moveTo(that.root, file2, null, testMove);
-            },
-            testMove = function(error) {
-                ok(typeof error !== 'undefined' && error !== null, "invalid file name should result in error");
-                equal(error.code, FileError.ENCODING_ERR, "error code should be FileError.ENCODING_ERR");
-
-                // cleanup
-                that.deleteEntry(file1);
-                QUnit.start();
-            };
-
-        // create a new file entry to kick off test
-        this.createFile(file1, entryCallback, this.fail);
-    });
-    module('FileReader model');
-    test("FileReader object should have correct methods", function() {
-        expect(6);
-        var reader = new FileReader();
-        ok(reader !== null, "new FileReader() should not be null.");
-        ok(typeof reader.readAsBinaryString === 'function', "FileReader object should have a readAsBinaryString function.");
-        ok(typeof reader.readAsDataURL === 'function', "FileReader object should have a readAsDataURL function.");
-        ok(typeof reader.readAsText === 'function', "FileReader object should have a readAsText function.");
-        ok(typeof reader.readAsArrayBuffer === 'function', "FileReader object should have a readAsArrayBuffer function.");
-        ok(typeof reader.abort === 'function', "FileReader object should have an abort function.");
-    });
-    module('FileReader read', {
-        setup: function() {
-            this.root = getFileSystemRoot(); 
-            this.fail = function(error) {
-                console.log('file error: ' + error.code);
-            };            
-        }
-    });
-    test("should read file properly, File object", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(1);
-            
-            // path of file
-        var fileName = "reader.txt",
-            filePath = this.root.fullPath + '/' + fileName;
-            // file content
-            rule = "There is an exception to every rule.  Except this one.",
-            // creates a FileWriter object
-            create_writer = function(fileEntry) {
-                fileEntry.createWriter(write_file, this.fail);
-            },
-            // writes file and reads it back in
-            write_file = function(writer) {
-                writer.onwriteend = read_file; 
-                writer.write(rule);
-            },
-            // reads file and compares content to what was written
-            read_file = function(evt) {
-                var reader = new FileReader();
-                reader.onloadend = function(evt) {
-                    console.log("read success");
-                    console.log(evt.target.result);
-                    ok(evt.target.result === rule, "reader.result should be equal to the text written.");
-                    QUnit.start();
-                };
-                var myFile = new File();
-                myFile.fullPath = filePath; 
-                reader.readAsText(myFile);
-            };
-        
-        // create a file, write to it, and read it in again
-        this.root.getFile(fileName, {create: true}, create_writer, this.fail);
-    });
-    test("should read file properly, Data URL", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(1);
-            
-            // path of file
-        var fileName = "reader.txt",
-            filePath = this.root.fullPath + '/' + fileName;
-            // file content
-            rule = "There is an exception to every rule.  Except this one.",
-            // creates a FileWriter object
-            create_writer = function(fileEntry) {
-                fileEntry.createWriter(write_file, this.fail);
-            },
-            // writes file and reads it back in
-            write_file = function(writer) {
-                writer.onwriteend = read_file; 
-                writer.write(rule);
-            },
-            // reads file and compares content to what was written
-            read_file = function(evt) {
-                var reader = new FileReader();
-                reader.onloadend = function(evt) {
-                    console.log("read success");
-                    console.log(evt.target.result);
-                    ok(evt.target.result.substr(0,23) === "data:text/plain;base64,", "reader.result should be base64 encoded.");
-                    QUnit.start();
-                };
-                var myFile = new File();
-                myFile.fullPath = filePath; 
-                reader.readAsDataURL(myFile);
-            };
-        
-        // create a file, write to it, and read it in again
-        this.root.getFile(fileName, {create: true}, create_writer, this.fail);
-    });
-    module('FileWriter model', {
-        // setup function will run before each test
-        setup: function() {
-            var that = this;
-            this.root = getFileSystemRoot(); 
-            this.fail = function(error) {
-                console.log('file error: ' + error.code);
-            };
-            // deletes file, if it exists, then invokes callback
-            this.deleteFile = function(fileName, callback) {
-                that.root.getFile(fileName, null, 
-                        // remove file system entry
-                        function(entry) {
-                            entry.remove(callback, that.fail); 
-                        },
-                        // doesn't exist
-                        callback);
-            };
-            // deletes and re-creates the specified file, then invokes callback
-            this.createFile = function(fileName, callback) {
-                // creates file
-                var create_file = function() {
-                    that.root.getFile(fileName, {create: true}, callback, that.fail);                
-                };
-                
-                // deletes file, then re-creates it
-                that.deleteFile(fileName, create_file);
-            };
-        }
-    });    
-    test("FileWriter object should have correct methods", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(5);
-        
-        // retrieve a FileWriter object
-        var fileName = "writer.methods",
-            that = this,
-            test_writer = function(fileEntry) {
-                fileEntry.createWriter(function(writer) {
-                    ok(typeof writer !== 'undefined' && writer !== null, "FileEntry.createWriter should return a FileWriter object.");
-                    ok(typeof writer.write === 'function', "FileWriter object should have a write function.");
-                    ok(typeof writer.seek === 'function', "FileWriter object should have a seek function.");
-                    ok(typeof writer.truncate === 'function', "FileWriter object should have a truncate function.");
-                    ok(typeof writer.abort === 'function', "FileWriter object should have an abort function.");
-
-                    // cleanup
-                    that.deleteFile(fileName);
-                    QUnit.start();
-                }, this.fail);
-            };
-
-        // test FileWriter
-        this.root.getFile(fileName, {create: true}, test_writer, this.fail);                        
-    });
-    test("should be able to write and append to file, createWriter", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-
-        var that = this,
-            fileName = "writer.append",
-            filePath = this.root.fullPath + '/' + fileName,
-            // file content
-            rule = "There is an exception to every rule.",
-            // for testing file length
-            length = rule.length,
-            // writes initial file content
-            write_file = function(fileEntry) {
-                fileEntry.createWriter(function(writer) {
-                    writer.onwriteend = function(evt) {
-                        ok(writer.length === length, "should have written " + length + " bytes");
-                        ok(writer.position === length, "position should be at " + length);
-                        append_file(writer);
-                    };
-                    writer.write(rule); 
-                }, that.fail);
-            }, 
-            // appends to file
-            append_file = function(writer) {
-                var exception = "  Except this one.";            
-                writer.onwriteend = function(evt) {
-                    ok(writer.length === length, "file length should be " + length);
-                    ok(writer.position === length, "position should be at " + length);
-
-                    // cleanup
-                    that.deleteFile(fileName);
-                    QUnit.start();
-                };
-                length += exception.length;
-                writer.seek(writer.length);
-                writer.write(exception); 
-            };
-        
-        // create file, then write and append to it
-        this.createFile(fileName, write_file);
-    });
-    test("should be able to write and append to file, File object", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(4);
-
-        var that = this,
-            fileName = "writer.append",
-            filePath = this.root.fullPath + '/' + fileName,
-            // file content
-            rule = "There is an exception to every rule.",
-            // for testing file length
-            length = rule.length,
-            // writes initial file content
-            write_file = function(file) {
-                var writer = new FileWriter(file);
-                    writer.onwriteend = function(evt) {
-		 console.log("first writer.length = " + writer.length);
-		 console.log("first writer.position = " + writer.position);
-                        ok(writer.length === length, "should have written " + length + " bytes");
-                        ok(writer.position === length, "position should be at " + length);
-                        append_file(writer);
-                    };
-                    writer.write(rule); 
-            }, 
-            // appends to file
-            append_file = function(writer) {
-                var exception = "  Except this one.";            
-                writer.onwriteend = function(evt) {
-		 console.log("next writer.length = " + writer.length);
-		 console.log("next writer.position = " + writer.position);
-                    ok(writer.length === length, "file length should be " + length);
-                    ok(writer.position === length, "position should be at " + length);
-
-                    // cleanup
-                    that.deleteFile(fileName);
-                    QUnit.start();
-                };
-                length += exception.length;
-                writer.seek(writer.length);
-                writer.write(exception); 
-            };
-        
-        // create file, then write and append to it
-		var file = new File();
-		file.fullPath = filePath;
-        write_file(file);
-    });
-    test("should be able to write XML data", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-
-        var that = this,
-            fileName = "writer.xml",
-            filePath = this.root.fullPath + '/' + fileName,
-            // file content
-            rule = '<?xml version="1.0" encoding="UTF-8"?>\n<test prop="ack">\nData\n</test>\n',
-            // for testing file length
-            length = rule.length,
-            // writes file content
-            write_file = function(fileEntry) {
-                fileEntry.createWriter(function(writer) {
-                    writer.onwriteend = function(evt) {
-						ok(writer.length === length, "should have written " + length + " bytes");
-                        ok(writer.position === length, "position should be at " + length);
-
-                        // cleanup
-                        that.deleteFile(fileName);
-                        QUnit.start();
-                    };
-                    writer.write(rule); 
-                }, that.fail);
-            };
-            
-        // creates file, then write XML data
-        this.createFile(fileName, write_file);
-    });
-    test("should be able to write JSON data", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-
-        var that = this,
-            fileName = "writer.json",
-            filePath = this.root.fullPath + '/' + fileName,
-            // file content
-            rule = '{ "name": "Guy Incognito", "email": "here@there.com" }',
-            // for testing file length
-            length = rule.length,
-            // writes file content
-            write_file = function(fileEntry) {
-                fileEntry.createWriter(function(writer) {
-                    writer.onwriteend = function(evt) {
-                        ok(writer.length === length, "should have written " + length + " bytes");
-                        ok(writer.position === length, "position should be at " + length);
-
-                        // cleanup
-                        that.deleteFile(fileName);
-                        QUnit.start();
-                    };
-                    writer.write(rule); 
-                }, that.fail);
-            };
-        
-        // creates file, then write JSON content
-        this.createFile(fileName, write_file);
-    });
-	test("should write and read special characters", function() {
-		 QUnit.stop(tests.TEST_TIMEOUT);
-		 expect(1);
-		 
-		 var that = this,
-			// path of file
-			fileName = "reader.txt",
-			filePath = this.root.fullPath + '/' + fileName,
-			// file content
-			rule = "H\u00EBll\u00F5 Euro \u20AC\u00A1",
-			// creates a FileWriter object
-			create_writer = function(fileEntry) {
-				fileEntry.createWriter(write_file, this.fail);
-			},
-			// writes file and reads it back in
-			write_file = function(writer) {
-				writer.onwriteend = read_file; 
-				writer.write(rule);
-			},
-			// reads file and compares content to what was written
-			read_file = function(evt) {
-				var reader = new FileReader();
-					reader.onloadend = function(evt) {
-					console.log("read success");
-					console.log(evt.target.result);
-					ok(evt.target.result === rule, "reader.result should be equal to the text written.");
-					// cleanup
-					that.deleteFile(fileName);
-					QUnit.start();
-				};
-				var myFile = new File();
-				myFile.fullPath = filePath; 
-				reader.readAsText(myFile);
-			};
-		 
-		 // create a file, write to it, and read it in again
-		 this.createFile(fileName, create_writer, this.fail);
-		 });
-    test("should be able to seek", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(5);
-        
-        var that = this,
-            fileName = "writer.seek",
-            // file content
-            rule = "There is an exception to every rule.  Except this one.",
-            // for testing file length
-            length = rule.length,
-            // writes file content and tests writer.seek
-            seek_file = function(fileEntry) {
-                fileEntry.createWriter(function(writer) {
-                    writer.onwriteend = function(evt) {
-                        ok(writer.position == length, "position should be at " + length); 
-                        writer.seek(-5);
-                        ok(writer.position == (length-5), "position should be at " + (length-5)); 
-                        writer.seek(100);
-                        ok(writer.position == length, "position should be at " + length); 
-                        writer.seek(10);
-                        ok(writer.position == 10, "position should be at 10"); 
-
-                        // cleanup
-                        that.deleteFile(fileName);
-                        QUnit.start();
-                    };
-                    writer.seek(-100);
-                    ok(writer.position == 0, "position should be at 0");        
-                    writer.write(rule);
-                }, that.fail);
-            };
-            
-        // creates file, then write JSON content
-        this.createFile(fileName, seek_file);
-    });
-    test("should be able to truncate", function() {
-        QUnit.stop(tests.TEST_TIMEOUT);
-        expect(2);
-        
-        var that = this,
-            fileName = "writer.truncate",
-            rule = "There is an exception to every rule.  Except this one.",
-            // writes file content 
-            write_file = function(fileEntry) {
-                fileEntry.createWriter(function(writer) {
-                    writer.onwriteend = function(evt) {
-                        truncate_file(writer);
-                    }; 
-                    writer.write(rule);
-                }, that.fail);
-            },
-            // and tests writer.truncate
-            truncate_file = function(writer) {
-                writer.onwriteend = function(evt) {
-                    ok(writer.length == 36, "file length should be 36");
-                    ok(writer.position == 36, "position should be at 36");  
-                    
-                    // cleanup
-                    that.deleteFile(fileName);
-                    QUnit.start();
-                }; 
-                writer.truncate(36);                
-            };
-
-        // creates file, writes to it, then truncates it
-        this.createFile(fileName, write_file);
-    });
-};
\ No newline at end of file
diff --git a/Res/mobile-spec/tests/geolocation.tests.js b/Res/mobile-spec/tests/geolocation.tests.js
deleted file mode 100644
index 3eeb93f..0000000
--- a/Res/mobile-spec/tests/geolocation.tests.js
+++ /dev/null
@@ -1,58 +0,0 @@
-Tests.prototype.GeoLocationTests = function() {	
-  Geolocation.usePhoneGap();
-	module('Geolocation (navigator.geolocation)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.geolocation != null, "navigator.geolocation should not be null.");
-	});
-	test("should contain a getCurrentPosition function", function() {
-		expect(2);
-		ok(typeof navigator.geolocation.getCurrentPosition != 'undefined' && navigator.geolocation.getCurrentPosition != null, "navigator.geolocation.getCurrentPosition should not be null.");
-		ok(typeof navigator.geolocation.getCurrentPosition == 'function', "navigator.geolocation.getCurrentPosition should be a function.");
-	});
-	test("should contain a watchPosition function", function() {
-		expect(2);
-		ok(typeof navigator.geolocation.watchPosition != 'undefined' && navigator.geolocation.watchPosition != null, "navigator.geolocation.watchPosition should not be null.");
-		ok(typeof navigator.geolocation.watchPosition == 'function', "navigator.geolocation.watchPosition should be a function.");
-	});
-	test("should contain a clearWatch function", function() {
-		expect(2);
-		ok(typeof navigator.geolocation.clearWatch != 'undefined' && navigator.geolocation.clearWatch != null, "navigator.geolocation.watchPosition should not be null.");
-		ok(typeof navigator.geolocation.clearWatch == 'function', "navigator.geolocation.clearWatch should be a function.");
-	});
-	test("getCurrentPosition success callback should be called with a Position object", function() {
-		expect(2);
-		QUnit.stop(this.TEST_TIMEOUT);
-		var win = function(p) {
-			ok(p.coords != null, "Position object returned in getCurrentPosition success callback has a 'coords' property.");
-			ok(p.timestamp != null, "Position object returned in getCurrentPosition success callback has a 'timestamp' property.");
-			start();
-		};
-		var fail = function() { start(); };
-		navigator.geolocation.getCurrentPosition(win, fail);
-	});
-	// TODO: Need to test error callback... how?
-	// TODO: Need to test watchPosition success callback, test that makes sure clearPosition works (how to test that a timer is getting cleared?)
-	// TODO: Need to test options object passed in. Members that need to be tested so far include:
-	//				- options.frequency: this is also labelled differently on some implementations (internval on iPhone/BlackBerry currently). 
-	module('Geolocation model');
-	test("should be able to define a Position object with coords and timestamp properties", function() {
-		expect(3);
-		var pos = new Position({}, new Date());
-		ok(pos != null, "new Position() should not be null.");
-		ok(typeof pos.coords != 'undefined' && pos.coords != null, "new Position() should include a 'coords' property.");
-		ok(typeof pos.timestamp != 'undefined' && pos.timestamp != null, "new Position() should include a 'timestamp' property.");
-	});
-	test("should be able to define a Coordinates object with latitude, longitude, accuracy, altitude, heading, speed and altitudeAccuracy properties", function() {
-		expect(8);
-		var coords = new Coordinates(1,2,3,4,5,6,7);
-		ok(coords != null, "new Coordinates() should not be null.");
-		ok(typeof coords.latitude != 'undefined' && coords.latitude != null, "new Coordinates() should include a 'latitude' property.");
-		ok(typeof coords.longitude != 'undefined' && coords.longitude != null, "new Coordinates() should include a 'longitude' property.");
-		ok(typeof coords.accuracy != 'undefined' && coords.accuracy != null, "new Coordinates() should include a 'accuracy' property.");
-		ok(typeof coords.altitude != 'undefined' && coords.altitude != null, "new Coordinates() should include a 'altitude' property.");
-		ok(typeof coords.heading != 'undefined' && coords.heading != null, "new Coordinates() should include a 'heading' property.");
-		ok(typeof coords.speed != 'undefined' && coords.speed != null, "new Coordinates() should include a 'speed' property.");
-		ok(typeof coords.altitudeAccuracy != 'undefined' && coords.altitudeAccuracy != null, "new Coordinates() should include a 'altitudeAccuracy' property.");
-	});
-};
diff --git a/Res/mobile-spec/tests/map.tests.js b/Res/mobile-spec/tests/map.tests.js
deleted file mode 100644
index 9dcf279..0000000
--- a/Res/mobile-spec/tests/map.tests.js
+++ /dev/null
@@ -1,12 +0,0 @@
-Tests.prototype.MapTests = function() {	
-	module('Map (navigator.map)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.map != null, "navigator.map should not be null.");
-	});
-	test("should contain a show function", function() {
-		expect(2);
-		ok(navigator.map.show != null, "navigator.map.show should not be null.");
-		ok(typeof navigator.map.show == 'function', "navigator.map.show should be a function.");
-	});
-};
\ No newline at end of file
diff --git a/Res/mobile-spec/tests/media.tests.js b/Res/mobile-spec/tests/media.tests.js
deleted file mode 100644
index 43f9b1c..0000000
--- a/Res/mobile-spec/tests/media.tests.js
+++ /dev/null
@@ -1,31 +0,0 @@
-//
-// @TODO Update to Latest HTML5 Audio Element Spec
-// @see http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html#audio
-//
-Tests.prototype.MediaTests = function() {	
-	module('Media (Audio)');
-	test("should exist", function() {
-  		expect(1);
-		ok(typeof Audio === "function" || typeof Audio === "object", "'Audio' should be defined as a function in global scope.");
-	});
-	test("should define constants for Media errors", function() {
-		expect(5);
-		ok(MediaError != null && typeof MediaError != 'undefined', "MediaError object exists in global scope.");
-		equals(MediaError.MEDIA_ERR_ABORTED, 1, "MediaError.MEDIA_ERR_ABORTED is equal to 1.");
-		equals(MediaError.MEDIA_ERR_NETWORK, 2, "MediaError.MEDIA_ERR_NETWORK is equal to 2.");
-		equals(MediaError.MEDIA_ERR_DECODE, 3, "MediaError.MEDIA_ERR_DECODE is equal to 3.");
-		equals(MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED, 4, "MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED is equal to 4.");
-	});
-	test("should contain 'src', 'loop' and 'error' properties", function() {
-  		expect(7);
-		var audioSrc = '/test.mp3';
-		var audio = new Audio(audioSrc);
-  		ok(typeof audio == "object", "Instantiated 'Audio' object instance should be of type 'object.'");
-		ok(audio.src != null && typeof audio.src != 'undefined', "Instantiated 'Audio' object's 'src' property should not be null or undefined.");
-		ok(audio.src.indexOf(audioSrc) >= 0, "Instantiated 'Audio' object's 'src' property should match constructor parameter.");
-		ok(audio.loop != null && typeof audio.loop != 'undefined', "Instantiated 'Audio' object's 'loop' property should not be null or undefined.");
-		ok(audio.loop == false, "Instantiated 'Audio' object's 'loop' property should initially be false.");
-		ok(typeof audio.error != 'undefined', "Instantiated 'Audio' object's 'error' property should not undefined.");
-		ok(audio.error == null, "Instantiated 'Audio' object's 'error' should initially be null.");
-	});
-};
\ No newline at end of file
diff --git a/Res/mobile-spec/tests/network.tests.js b/Res/mobile-spec/tests/network.tests.js
deleted file mode 100644
index a7dc69d..0000000
--- a/Res/mobile-spec/tests/network.tests.js
+++ /dev/null
@@ -1,30 +0,0 @@
-Tests.prototype.NetworkTests = function() {
-	module('Network (navigator.network)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.network != null, "navigator.network should not be null.");
-	});
-	test("should contain an isReachable function", function() {
-		expect(2);
-		ok(typeof navigator.network.isReachable != 'undefined' && navigator.network.isReachable != null, "navigator.network.isReachable should not be null.");
-		ok(typeof navigator.network.isReachable == 'function', "navigator.network.isReachable should be a function.");
-	});
-	test("should define constants for network status", function() {
-		expect(4);
-		ok(NetworkStatus != null, "NetworkStatus object exists in global scope.");
-		equals(NetworkStatus.NOT_REACHABLE, 0, "NetworkStatus.NOT_REACHABLE is equal to 0.");
-		equals(NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK, 1, "NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK is equal to 1.");
-		equals(NetworkStatus.REACHABLE_VIA_WIFI_NETWORK, 2, "NetworkStatus.REACHABLE_VIA_WIFI_NETWORK is equal to 2.");
-	});
-	test("isReachable function should return one of the defined NetworkStatus constants to its success callback", function() {
-		expect(1);
-		QUnit.stop(this.TEST_TIMEOUT);
-		var hostname = "http://www.google.com";
-		var win = function(code) {
-      debugPrint("Network Code" + code);
-			ok(code == NetworkStatus.NOT_REACHABLE || code == NetworkStatus.REACHABLE_VIA_CARRIER_DATA_NETWORK || code == NetworkStatus.REACHABLE_VIA_WIFI_NETWORK, "Success callback in isReachable returns one of the defined NetworkStatus constants.");
-			start();
-		};
-		navigator.network.isReachable(hostname, win);
-	});
-};
diff --git a/Res/mobile-spec/tests/notification.tests.js b/Res/mobile-spec/tests/notification.tests.js
deleted file mode 100644
index 03e3885..0000000
--- a/Res/mobile-spec/tests/notification.tests.js
+++ /dev/null
@@ -1,22 +0,0 @@
-Tests.prototype.NotificationTests = function() {	
-	module('Notification (navigator.notification)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.notification != null, "navigator.notification should not be null.");
-	});
-	test("should contain a vibrate function", function() {
-		expect(2);
-		ok(typeof navigator.notification.vibrate != 'undefined' && navigator.notification.vibrate != null, "navigator.notification.vibrate should not be null.");
-		ok(typeof navigator.notification.vibrate == 'function', "navigator.notification.vibrate should be a function.");
-	});
-	test("should contain a beep function", function() {
-		expect(2);
-		ok(typeof navigator.notification.beep != 'undefined' && navigator.notification.beep != null, "navigator.notification.beep should not be null.");
-		ok(typeof navigator.notification.beep == 'function', "navigator.notification.beep should be a function.");
-	});
-	test("should contain a alert function", function() {
-		expect(2);
-		ok(typeof navigator.notification.alert != 'undefined' && navigator.notification.alert != null, "navigator.notification.alert should not be null.");
-		ok(typeof navigator.notification.alert == 'function', "navigator.notification.alert should be a function.");
-	});
-};
\ No newline at end of file
diff --git a/Res/mobile-spec/tests/orientation.tests.js b/Res/mobile-spec/tests/orientation.tests.js
deleted file mode 100644
index 1be55c3..0000000
--- a/Res/mobile-spec/tests/orientation.tests.js
+++ /dev/null
@@ -1,34 +0,0 @@
-Tests.prototype.OrientationTests = function() {	
-	module('Orientation (navigator.orientation)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.orientation != null, "navigator.orientation should not be null.");
-	});
-	test("should have an initially null lastPosition property", function() {
-  		expect(1);
-  		ok(typeof navigator.orientation.currentOrientation != 'undefined' && navigator.orientation.currentOrientation == null, "navigator.orientation.currentOrientation should be initially null.");
-	});
-	test("should contain a getCurrentOrientation function", function() {
-		expect(2);
-		ok(typeof navigator.orientation.getCurrentOrientation != 'undefined' && navigator.orientation.getCurrentOrientation != null, "navigator.orientation.getCurrentOrientation should not be null.");
-		ok(typeof navigator.orientation.getCurrentOrientation == 'function', "navigator.orientation.getCurrentOrientation should be a function.");
-	});
-	test("should contain a watchOrientation function", function() {
-		expect(2);
-		ok(typeof navigator.orientation.watchOrientation != 'undefined' && navigator.orientation.watchOrientation != null, "navigator.orientation.watchOrientation should not be null.");
-		ok(typeof navigator.orientation.watchOrientation == 'function', "navigator.orientation.watchOrientation should be a function.");
-	});
-	// TODO: add tests for DisplayOrientation constants?
-	test("getCurrentOrientation success callback should be called with an Orientation enumeration", function() {
-		expect(2);
-		QUnit.stop(tests.TEST_TIMEOUT);
-		var win = function(orient) {
-			ok(0 <= orient <= 6, "Position object returned in getCurrentPosition success callback is a valid DisplayOrientation value.");
-			equals(orient, navigator.orientation.currentOrientation, "Orientation value returned in getCurrentOrientation success callback equals navigator.orientation.currentOrientation.");
-			start();
-		};
-		var fail = function() { start(); };
-		navigator.orientation.getCurrentOrientation(win, fail);
-	});
-	// TODO: Need to test watchPosition success callback, test that makes sure clearPosition works (how to test that a timer is getting cleared?)
-};
\ No newline at end of file
diff --git a/Res/mobile-spec/tests/sms.tests.js b/Res/mobile-spec/tests/sms.tests.js
deleted file mode 100644
index f3e1b15..0000000
--- a/Res/mobile-spec/tests/sms.tests.js
+++ /dev/null
@@ -1,12 +0,0 @@
-Tests.prototype.SMSTests = function() {	
-	module('SMS (navigator.sms)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.sms != null, "navigator.sms should not be null.");
-	});
-	test("should contain a send function", function() {
-		expect(2);
-		ok(typeof navigator.sms.send != 'undefined' && navigator.sms.send != null, "navigator.sms.send should not be null.");
-		ok(typeof navigator.sms.send == 'function', "navigator.sms.send should be a function.");
-	});
-};
\ No newline at end of file
diff --git a/Res/mobile-spec/tests/storage.tests.js b/Res/mobile-spec/tests/storage.tests.js
deleted file mode 100644
index 41476d8..0000000
--- a/Res/mobile-spec/tests/storage.tests.js
+++ /dev/null
@@ -1,170 +0,0 @@
-Tests.prototype.StorageTests = function() 
-{
-  module("Session Storage");
-  test("should exist", function() {
-	expect(7);
-	ok(window.sessionStorage != null, "sessionStorage is defined");
-    ok(typeof window.sessionStorage.length != 'undefined', "sessionStorage.length is defined");
-    ok(typeof(window.sessionStorage.key) == "function", "sessionStorage.key is defined");
-    ok(typeof(window.sessionStorage.getItem) == "function", "sessionStorage.getItem is defined");
-    ok(typeof(window.sessionStorage.setItem) == "function", "sessionStorage.setItem is defined");
-    ok(typeof(window.sessionStorage.removeItem) == "function", "sessionStorage.removeItem is defined");
-    ok(typeof(window.sessionStorage.clear) == "function", "sessionStorage.clear is defined");
-  });
-  test("check length", function() {
-    expect(3);
-    ok(window.sessionStorage.length == 0, "length should be 0");
-    window.sessionStorage.setItem("key","value");
-    ok(window.sessionStorage.length == 1, "length should be 1");
-    window.sessionStorage.removeItem("key");   
-    ok(window.sessionStorage.length == 0, "length should be 0");
-  });
-  test("check key", function() {
-	expect(3);
-	ok(window.sessionStorage.key(0) == null, "key should be null");
-	window.sessionStorage.setItem("test","value");
-	ok(window.sessionStorage.key(0) == "test", "key should be 'test'");
-	window.sessionStorage.removeItem("test");   
-	ok(window.sessionStorage.key(0) == null, "key should be null");
-  });
-  test("check getItem", function() {
-	expect(3);
-    ok(window.sessionStorage.getItem("item") == null, "item should be null");
-    window.sessionStorage.setItem("item","value");
-    ok(window.sessionStorage.getItem("item") == "value", "The value of the item should be 'value'");
-    window.sessionStorage.removeItem("item");   
-    ok(window.sessionStorage.getItem("item") == null, "item should be null");
-  });
-  test("check setItem", function() {
-    expect(4);
-    ok(window.sessionStorage.getItem("item") == null, "item should be null");
-    window.sessionStorage.setItem("item","value");
-    ok(window.sessionStorage.getItem("item") == "value", "The value of the item should be 'value'");
-    window.sessionStorage.setItem("item","newval");
-    ok(window.sessionStorage.getItem("item") == "newval", "The value of the item should be 'newval'");
-    window.sessionStorage.removeItem("item");   
-    ok(window.sessionStorage.getItem("item") == null, "item should be null");
-  });
-  test("check removeItem", function() {
-    expect(3);
-    ok(window.sessionStorage.getItem("item") == null, "item should be null");
-    window.sessionStorage.setItem("item","value");
-    ok(window.sessionStorage.getItem("item") == "value", "The value of the item should be 'value'");
-    window.sessionStorage.removeItem("item");   
-    ok(window.sessionStorage.getItem("item") == null, "item should be null");
-  });
-  test("check clear", function() {
-    expect(11);
-    ok(window.sessionStorage.getItem("item1") == null, "item1 should be null");
-    ok(window.sessionStorage.getItem("item2") == null, "item2 should be null");
-    ok(window.sessionStorage.getItem("item3") == null, "item3 should be null");
-    window.sessionStorage.setItem("item1","value");
-    window.sessionStorage.setItem("item2","value");
-    window.sessionStorage.setItem("item3","value");
-    ok(window.sessionStorage.getItem("item1") == "value", "item1 should be null");
-    ok(window.sessionStorage.getItem("item2") == "value", "item2 should be null");
-    ok(window.sessionStorage.getItem("item3") == "value", "item3 should be null");	    
-    ok(window.sessionStorage.length == 3, "length should be 3");
-    window.sessionStorage.clear();
-    ok(window.sessionStorage.length == 0, "length should be 0");
-    ok(window.sessionStorage.getItem("item1") == null, "item1 should be null");
-    ok(window.sessionStorage.getItem("item2") == null, "item2 should be null");
-    ok(window.sessionStorage.getItem("item3") == null, "item3 should be null");	    
-  });
-  test("check dot notation", function() {
-    expect(3);
-    ok(window.sessionStorage.item == null, "item should be null");
-    window.sessionStorage.item = "value";
-    ok(window.sessionStorage.item == "value", "The value of the item should be 'value'");
-    window.sessionStorage.removeItem("item");   
-    ok(window.sessionStorage.item == null, "item should be null");
-  });
-  module("Local Storage");
-  test("should exist", function() {
-	expect(7);
-	ok(window.localStorage != null, "localStorage is defined");
-    ok(typeof window.localStorage.length != 'undefined', "localStorage.length is defined");
-    ok(typeof(window.localStorage.key) == "function", "localStorage.key is defined");
-    ok(typeof(window.localStorage.getItem) == "function", "localStorage.getItem is defined");
-    ok(typeof(window.localStorage.setItem) == "function", "localStorage.setItem is defined");
-    ok(typeof(window.localStorage.removeItem) == "function", "localStorage.removeItem is defined");
-    ok(typeof(window.localStorage.clear) == "function", "localStorage.clear is defined");
-  });  
-  test("check length", function() {
-    expect(3);
-    ok(window.localStorage.length == 0, "length should be 0");
-    window.localStorage.setItem("key","value");
-    ok(window.localStorage.length == 1, "length should be 1");
-    window.localStorage.removeItem("key");   
-    ok(window.localStorage.length == 0, "length should be 0");
-  });
-  test("check key", function() {
-    expect(3);
-    ok(window.localStorage.key(0) == null, "key should be null");
-    window.localStorage.setItem("test","value");
-    ok(window.localStorage.key(0) == "test", "key should be 'test'");
-    window.localStorage.removeItem("test");   
-    ok(window.localStorage.key(0) == null, "key should be null");
-  });
-  test("check getItem", function() {
-    expect(3);
-    ok(window.localStorage.getItem("item") == null, "item should be null");
-    window.localStorage.setItem("item","value");
-    ok(window.localStorage.getItem("item") == "value", "The value of the item should be 'value'");
-    window.localStorage.removeItem("item");   
-    ok(window.localStorage.getItem("item") == null, "item should be null");
-  });
-  test("check setItem", function() {
-    expect(4);
-    ok(window.localStorage.getItem("item") == null, "item should be null");
-    window.localStorage.setItem("item","value");
-    ok(window.localStorage.getItem("item") == "value", "The value of the item should be 'value'");
-    window.localStorage.setItem("item","newval");
-    ok(window.localStorage.getItem("item") == "newval", "The value of the item should be 'newval'");
-    window.localStorage.removeItem("item");   
-    ok(window.localStorage.getItem("item") == null, "item should be null");
-  });
-  test("check removeItem", function() {
-    expect(3);
-    ok(window.localStorage.getItem("item") == null, "item should be null");
-    window.localStorage.setItem("item","value");
-    ok(window.localStorage.getItem("item") == "value", "The value of the item should be 'value'");
-    window.localStorage.removeItem("item");   
-    ok(window.localStorage.getItem("item") == null, "item should be null");
-  });
-  test("check clear", function() {
-    expect(11);
-    ok(window.localStorage.getItem("item1") == null, "item1 should be null");
-    ok(window.localStorage.getItem("item2") == null, "item2 should be null");
-    ok(window.localStorage.getItem("item3") == null, "item3 should be null");
-    window.localStorage.setItem("item1","value");
-    window.localStorage.setItem("item2","value");
-    window.localStorage.setItem("item3","value");
-    ok(window.localStorage.getItem("item1") == "value", "item1 should be null");
-    ok(window.localStorage.getItem("item2") == "value", "item2 should be null");
-    ok(window.localStorage.getItem("item3") == "value", "item3 should be null");	    
-    ok(window.localStorage.length == 3, "length should be 3");
-    window.localStorage.clear();
-    ok(window.localStorage.length == 0, "length should be 0");
-    ok(window.localStorage.getItem("item1") == null, "item1 should be null");
-    ok(window.localStorage.getItem("item2") == null, "item2 should be null");
-    ok(window.localStorage.getItem("item3") == null, "item3 should be null");	    
-  });
-  test("check dot notation", function() {
-    expect(3);
-    ok(window.localStorage.item == null, "item should be null");
-    window.localStorage.item = "value";
-    ok(window.localStorage.item == "value", "The value of the item should be 'value'");
-    window.localStorage.removeItem("item");   
-    ok(window.localStorage.item == null, "item should be null");
-  });
-  module("HTML 5 Storage");
-  test("should exist", function() {
-    expect(1);
-    ok(typeof(window.openDatabase) == "function", "Database is defined");
-  });
-  test("Should open a database", function() {
-    var db = openDatabase("Database", "1.0", "HTML5 Database API example", 200000);
-    ok(db != null, "Database should be opened");
-  });
-}
diff --git a/Res/mobile-spec/tests/system.tests.js b/Res/mobile-spec/tests/system.tests.js
deleted file mode 100644
index c76fdb5..0000000
--- a/Res/mobile-spec/tests/system.tests.js
+++ /dev/null
@@ -1,261 +0,0 @@
-Tests.prototype.SystemTests = function() {
-	module('System Information (navigator.system)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.system != null, "navigator.system should not be null.");
-	});
-	test("should contain a get function", function() {
-		expect(2);
-		ok(typeof navigator.system.get != 'undefined' && navigator.system.get != null, "navigator.system.get should not be null.");
-		ok(typeof navigator.system.get == 'function', "navigator.system.get should be a function.");
-	});
-	test("should contain a has function", function() {
-		expect(2);
-		ok(typeof navigator.system.has != 'undefined' && navigator.system.has != null, "navigator.system.has should not be null.");
-		ok(typeof navigator.system.has == 'function', "navigator.system.has should be a function.");
-	});
-	test("should contain a monitor function", function() {
-		expect(2);
-		ok(typeof navigator.system.monitor != 'undefined' && navigator.system.monitor != null, "navigator.system.monitor should not be null.");
-		ok(typeof navigator.system.monitor == 'function', "navigator.system.monitor should be a function.");
-	});
-	module('System Information Options');
-	test("should be able to define a SystemInfoOptions object", function() {
-		expect(6);
-		var systemInfoOptions = new SystemInfoOptions(0.0, 0.0, "a", 0, "b");
-		ok(systemInfoOptions != null, "new SystemInfoOptions() should not be null.");
-		ok(typeof systemInfoOptions.highThreshold != 'undefined' && systemInfoOptions.highThreshold != null && systemInfoOptions.highThreshold == 0.0, "new SystemInfoOptions() should include a 'highThreshold' property.");
-		ok(typeof systemInfoOptions.lowThreshold != 'undefined' && systemInfoOptions.lowThreshold != null && systemInfoOptions.lowThreshold == 0.0, "new SystemInfoOptions() should include a 'lowThreshold' property.");
-		ok(typeof systemInfoOptions.thresholdTarget != 'undefined' && systemInfoOptions.thresholdTarget != null && systemInfoOptions.thresholdTarget == "a", "new SystemInfoOptions() should include a 'thresholdTarget' property.");
-		ok(typeof systemInfoOptions.timeout != 'undefined' && systemInfoOptions.timeout != null && systemInfoOptions.timeout == 0, "new SystemInfoOptions() should include a 'timeout' property.");
-		ok(typeof systemInfoOptions.id != 'undefined' && systemInfoOptions.id != null && systemInfoOptions.id == "b", "new SystemInfoOptions() should include a 'id' property.");
-	});	
-	module('Power Property');
-	test("should be able to define a Power Property object", function() {
-		expect(7);
-		var power = new PowerAttributes("a","b",0.0,0,true,false);
-		ok(power != null, "new PowerAttributes() should not be null.");
-		ok(typeof power.info != 'undefined' && power.info != null && power.info == "a", "new PowerAttributes() should include a 'info' property.");
-		ok(typeof power.id != 'undefined' && power.id != null && power.id == "b", "new PowerAttributes() should include a 'id' property.");
-		ok(typeof power.level != 'undefined' && power.level != null && power.level == 0.0, "new PowerAttributes() should include a 'level' property.");
-		ok(typeof power.timeRemaining != 'undefined' && power.timeRemaining != null && power.timeRemaining == 0, "new PowerAttributes() should include a 'timeRemaining' property.");
-		ok(typeof power.isBattery != 'undefined' && power.isBattery != null && power.isBattery == true, "new PowerAttributes() should include a 'isBattery' property.");
-		ok(typeof power.isCharging != 'undefined' && power.isCharging != null && power.isCharging == false, "new PowerAttributes() should include a 'isCharging' property.");
-	});	
-	module('CPU Property');
-	test("should be able to define a CPU Property object", function() {
-		expect(4);
-		var cpu = new CPUAttributes("a", "b", 0.0);
-		ok(cpu  != null, "new CPUAttributes() should not be null.");
-		ok(typeof cpu.info != 'undefined' && cpu.info != null && cpu.info == "a", "new CPUAttributes() should include a 'info' property.");
-		ok(typeof cpu.id != 'undefined' && cpu.id != null && cpu.id == "b", "new CPUAttributes() should include a 'id' property.");
-		ok(typeof cpu.usage != 'undefined' && cpu.usage != null && cpu.usage == 0.0, "new CPUAttributes() should include a 'usage' property.");
-	});	
-	module('Thermal Property');
-	test("should be able to define a Thermal Property object", function() {
-		expect(4);
-		var thermal = new ThermalAttributes("a", "b", 0.0);
-		ok(thermal  != null, "new ThermalAttributes() should not be null.");
-		ok(typeof thermal.info != 'undefined' && thermal.info != null && thermal.info == "a", "new ThermalAttributes() should include a 'info' property.");
-		ok(typeof thermal.id != 'undefined' && thermal.id != null && thermal.id == "b", "new ThermalAttributes() should include a 'id' property.");
-		ok(typeof thermal.state != 'undefined' && thermal.state != null && thermal.state == 0.0, "new ThermalAttributes() should include a 'state' property.");
-	});	
-	module('Network Property');
-	test("should be able to define a Network Property object", function() {
-		expect(4);
-		var network = new NetworkAttributes("a", "b", []);
-		ok(network  != null, "new NetworkAttributes() should not be null.");
-		ok(typeof network.info != 'undefined' && network.info != null && network.info == "a", "new NetworkAttributes() should include a 'info' property.");
-		ok(typeof network.id != 'undefined' && network.id != null && network.id == "b", "new NetworkAttributes() should include a 'id' property.");
-		ok(typeof network.activeConnections != 'undefined' && network.activeConnections != null, "new NetworkAttributes() should include a 'activeConnections' property.");
-	});	
-	module('Connection Type Property');
-	test("should be able to define a display Type Property object", function() {
-		expect(10);
-		var connection = new ConnectionAttributes('a', 'b', ConnectionType.UNKNOWN, 0, 0, 0, 0, 0.0, false);
-		ok(connection  != null, "new displayAttributes() should not be null.");
-		ok(typeof connection.info != 'undefined' && connection.info != null && connection.info == "a", "new ConnectionAttributes() should include a 'info' property.");
-		ok(typeof connection.id != 'undefined' && connection.id != null && connection.id == "b", "new ConnectionAttributes() should include a 'id' property.");
-		ok(typeof connection.type != 'undefined' && connection.type != null && connection.type == 'unknown', "new ConnectionAttributes() should include a 'type' property.");
-		ok(typeof connection.currentDownloadBandwidth != 'undefined' && connection.currentDownloadBandwidth != null && connection.currentDownloadBandwidth == 0, "new ConnectionAttributes() should include a 'currentDownloadBandwidth' property.");
-		ok(typeof connection.currentUploadBandwidth != 'undefined' && connection.currentUploadBandwidth != null && connection.currentUploadBandwidth == 0, "new ConnectionAttributes() should include a 'currentUploadBandwidth' property.");
-		ok(typeof connection.maxDownloadBandwidth != 'undefined' && connection.maxDownloadBandwidth != null && connection.maxDownloadBandwidth == 0, "new ConnectionAttributes() should include a 'maxDownloadBandwidth' property.");
-		ok(typeof connection.maxUploadBandwidth != 'undefined' && connection.maxUploadBandwidth != null && connection.maxUploadBandwidth == 0, "new ConnectionAttributes() should include a 'maxUploadBandwidth' property.");
-		ok(typeof connection.currentSignalStrength != 'undefined' && connection.currentSignalStrength != null && connection.currentSignalStrength == 0.0, "new ConnectionAttributes() should include a 'currentSignalStrength' property.");
-		ok(typeof connection.roaming != 'undefined' && connection.roaming != null && connection.roaming == false, "new ConnectionAttributes() should include a 'roaming' property.");
-	});	
-	module('Sensor Property');
-	test("should be able to define a Sensor Property object", function() {
-		expect(5);
-		var sensor = new SensorAttributes(0.0,0.0,0.0,0.0);
-		ok(sensor  != null, "new SensorAttributes() should not be null.");
-		ok(typeof sensor.value != 'undefined' && sensor.value != null && sensor.value == 0.0, "new SensorAttributes() should include a 'value' property.");
-		ok(typeof sensor.min != 'undefined' && sensor.min != null && sensor.min == 0.0, "new SensorAttributes() should include a 'min' property.");
-		ok(typeof sensor.max != 'undefined' && sensor.max != null && sensor.max == 0.0, "new SensorAttributes() should include a 'max' property.");
-		ok(typeof sensor.normalizedValue != 'undefined' && sensor.normalizedValue != null && sensor.normalizedValue == 0.0, "new SensorAttributes() should include a 'normalizedValue' property.");
-	});	
-	module('AVCodecs Property');
-	test("should be able to define a AVCodecs Property object", function() {
-		expect(5);
-		var avcodecs = new AVCodecsAttributes("a", "b", [], []);
-		ok(avcodecs  != null, "new AVCodecsAttributes() should not be null.");
-		ok(typeof avcodecs.info != 'undefined' && avcodecs.info != null && avcodecs.info == "a", "new AVCodecsAttributes() should include a 'info' property.");
-		ok(typeof avcodecs.id != 'undefined' && avcodecs.id != null && avcodecs.id == "b", "new AVCodecsAttributes() should include a 'id' property.");
-		ok(typeof avcodecs.audioCodecs != 'undefined' && avcodecs.audioCodecs != null, "new AVCodecsAttributes() should include a 'audioCodecs' property.");
-		ok(typeof avcodecs.videoCodecs != 'undefined' && avcodecs.videoCodecs != null, "new AVCodecsAttributes() should include a 'videoCodecs' property.");
-	});	
-	module('Audio Codec Property');
-	test("should be able to define a Audio Codec Property object", function() {
-		expect(6);
-		var codec = new AudioCodecAttributes("a", "b", 'a',true,true);
-		ok(codec != null, "new AudioCodecAttributes() should not be null.");
-		ok(typeof codec.info != 'undefined' && codec.info != null && codec.info == "a", "new AudioCodecAttributes() should include a 'info' property.");
-		ok(typeof codec.id != 'undefined' && codec.id != null && codec.id == "b", "new AudioCodecAttributes() should include a 'id' property.");
-		ok(typeof codec.compFormats != 'undefined' && codec.compFormats != null && codec.compFormats == 'a', "new AudioCodecAttributes() should include a 'compFormats' property.");
-		ok(typeof codec.encode != 'undefined' && codec.encode != null && codec.encode == true, "new AudioCodecAttributes() should include a 'encode' property.");
-		ok(typeof codec.decode != 'undefined' && codec.decode != null && codec.decode == true, "new AudioCodecAttributes() should include a 'decode' property.");
-	});	
-	module('Video Codec Property');
-	test("should be able to define a Video Codec Property object", function() {
-		expect(9);
-		var codec = new VideoCodecAttributes("a", "b", [],[],[],[],[],[]);
-		ok(codec != null, "new VideoCodecAttributes() should not be null.");
-		ok(typeof codec.info != 'undefined' && codec.info != null && codec.info == "a", "new VideoCodecAttributes() should include a 'info' property.");
-		ok(typeof codec.id != 'undefined' && codec.id != null && codec.id == "b", "new VideoCodecAttributes() should include a 'id' property.");
-		ok(typeof codec.compFormats != 'undefined' && codec.compFormats != null, "new VideoCodecAttributes() should include a 'compFormats' property.");
-		ok(typeof codec.containerFormats != 'undefined' && codec.containerFormats != null, "new VideoCodecAttributes() should include a 'containerFormats' property.");
-		ok(typeof codec.hwAccel != 'undefined' && codec.hwAccel != null, "new VideoCodecAttributes() should include a 'hwAccel' property.");
-		ok(typeof codec.profiles != 'undefined' && codec.profiles != null, "new VideoCodecAttributes() should include a 'profiles' property.");
-		ok(typeof codec.frameTypes != 'undefined' && codec.frameTypes != null, "new VideoCodecAttributes() should include a 'frameTypes' property.");
-		ok(typeof codec.rateTypes != 'undefined' && codec.rateTypes != null, "new VideoCodecAttributes() should include a 'rateTypes' property.");
-	});	
-	module('Storage Unit Property');
-	test("should be able to define a Storage Property object", function() {
-		expect(8);
-		var storage = new StorageUnitAttributes('a','b',0,true,0,0,true);
-		ok(storage != null, "new StorageUnitAttributes() should not be null.");
-		ok(typeof storage.info != 'undefined' && storage.info != null && storage.info == "a", "new StorageUnitAttributes() should include a 'info' property.");
-		ok(typeof storage.id != 'undefined' && storage.id != null && storage.id == "b", "new StorageUnitAttributes() should include a 'id' property.");
-		ok(typeof storage.type != 'undefined' && storage.type != null && storage.type == 0, "new StorageUnitAttributes() should include a 'type' property.");
-		ok(typeof storage.isWritable != 'undefined' && storage.isWritable != null && storage.isWritable == true, "new StorageUnitAttributes() should include a 'isWritable' property.");
-		ok(typeof storage.capacity != 'undefined' && storage.capacity != null && storage.capacity == 0, "new StorageUnitAttributes() should include a 'capacity' property.");
-		ok(typeof storage.availableCapacity != 'undefined' && storage.availableCapacity != null && storage.availableCapacity == 0, "new StorageUnitAttributes() should include a 'availableCapacity' property.");
-		ok(typeof storage.isRemoveable != 'undefined' && storage.isRemoveable != null && storage.isRemoveable == true, "new StorageUnitAttributes() should include a 'isRemoveable' property.");
-	});	
-	module('Output Devices Property');
-	test("should be able to define a Input Devices Property object", function() {
-		expect(11);
-		var output = new OutputDevicesAttributes('a','b',[],[],[],"a",[],"a",[],[]);
-		ok(output != null, "new OutputDevicesAttributes() should not be null.");
-		ok(typeof output.info != 'undefined' && output.info != null && output.info == "a", "new OutputDevicesAttributes() should include a 'info' property.");
-		ok(typeof output.id != 'undefined' && output.id != null && output.id == "b", "new OutputDevicesAttributes() should include a 'id' property.");
-		ok(typeof output.displayDevices != 'undefined' && output.displayDevices != null, "new OutputDevicesAttributes() should include a 'displayDevices' property.");
-		ok(typeof output.activeDisplayDevices != 'undefined' && output.activeDisplayDevices != null, "new OutputDevicesAttributes() should include a 'activeDisplayDevices' property.");
-		ok(typeof output.printingDevices != 'undefined' && output.printingDevices != null, "new OutputDevicesAttributes() should include a 'printingDevices' property.");
-		ok(typeof output.activePrintingDevice != 'undefined' && output.activePrintingDevice != null && output.activePrintingDevice == "a", "new OutputDevicesAttributes() should include a 'activePrintingDevice' property.");
-		ok(typeof output.brailleDevices != 'undefined' && output.brailleDevices != null, "new OutputDevicesAttributes() should include a 'brailleDevices' property.");
-		ok(typeof output.activeBrailleDevice != 'undefined' && output.activeBrailleDevice != null && output.activeBrailleDevice == "a", "new OutputDevicesAttributes() should include a 'activeBrailleDevice' property.");
-		ok(typeof output.audioDevices != 'undefined' && output.audioDevices != null, "new OutputDevicesAttributes() should include a 'audioDevices' property.");
-		ok(typeof output.activeAudioDevices != 'undefined' && output.activeAudioDevices != null, "new OutputDevicesAttributes() should include a 'activeAudioDevices' property.");
-	});	
-	module('Display Device Type Property');
-	test("should be able to define a Display Device Property object", function() {
-		expect(10);
-		var display = new DisplayDeviceAttributes(0,0.0,0.0,true,0,0,0.0,0.0,"a");
-		ok(display  != null, "new DisplayDeviceAttributes() should not be null.");
-		ok(typeof display.orientation != 'undefined' && display.orientation != null && display.orientation == 0, "new DisplayDeviceAttributes() should include a 'orientation' property.");
-		ok(typeof display.brightness != 'undefined' && display.brightness != null && display.brightness == 0.0, "new DisplayDeviceAttributes() should include a 'brightness' property.");
-		ok(typeof display.contrast != 'undefined' && display.contrast != null && display.contrast == 0.0, "new DisplayDeviceAttributes() should include a 'contrast' property.");
-		ok(typeof display.blanked != 'undefined' && display.blanked != null && display.blanked == true, "new DisplayDeviceAttributes() should include a 'blanked' property.");
-		ok(typeof display.dotsPerInchW != 'undefined' && display.dotsPerInchW != null && display.dotsPerInchW == 0, "new DisplayDeviceAttributes() should include a 'dotsPerInchW' property.");
-		ok(typeof display.dotsPerInchH != 'undefined' && display.dotsPerInchH != null && display.dotsPerInchH == 0, "new DisplayDeviceAttributes() should include a 'dotsPerInchH' property.");
-		ok(typeof display.physicalWidth != 'undefined' && display.physicalWidth != null && display.physicalWidth == 0.0, "new DisplayDeviceAttributes() should include a 'physicalWidth' property.");
-		ok(typeof display.physicalHeight != 'undefined' && display.physicalHeight != null && display.physicalHeight == 0.0, "new DisplayDeviceAttributes() should include a 'physicalHeight' property.");
-		ok(typeof display.info != 'undefined' && display.info != null && display.info == 'a', "new DisplayDeviceAttributes() should include a 'info' property.");
-	});	
-	module('Audio Device Type Property');
-	test("should be able to define a Audio Device Property object", function() {
-		expect(6);
-		var audio = new AudioDeviceAttributes(0,0,0,0,"a");
-		ok(audio  != null, "new AudioDeviceAttributes() should not be null.");
-		ok(typeof audio.type != 'undefined' && audio.type != null && audio.type == 0, "new AudioDeviceAttributes() should include a 'type' property.");
-		ok(typeof audio.freqRangeLow != 'undefined' && audio.freqRangeLow != null && audio.freqRangeLow == 0, "new AudioDeviceAttributes() should include a 'freqRangeLow' property.");
-		ok(typeof audio.freqRangeHigh != 'undefined' && audio.freqRangeHigh != null && audio.freqRangeHigh == 0, "new AudioDeviceAttributes() should include a 'freqRangeHigh' property.");
-		ok(typeof audio.volumeLevel != 'undefined' && audio.volumeLevel != null && audio.volumeLevel == 0, "new AudioDeviceAttributes() should include a 'volumeLevel' property.");
-		ok(typeof audio.info != 'undefined' && audio.info != null && audio.info == "a", "new AudioDeviceAttributes() should include a 'info' property.");
-	});	
-	module('Printing Device Type Property');
-	test("should be able to define a Printing Device Property object", function() {
-		expect(5);
-		var printer = new PrintingDeviceAttributes(0,0,0,"a");
-		ok(printer  != null, "new PrintingDeviceAttributes() should not be null.");
-		ok(typeof printer.type != 'undefined' && printer.type != null && printer.type == 0, "new PrintingDeviceAttributes() should include a 'type' property.");
-		ok(typeof printer.resolution != 'undefined' && printer.resolution != null && printer.resolution == 0, "new PrintingDeviceAttributes() should include a 'resolution' property.");
-		ok(typeof printer.color != 'undefined' && printer.color != null && printer.color == 0, "new PrintingDeviceAttributes() should include a 'color' property.");
-		ok(typeof printer.info != 'undefined' && printer.info != null && printer.info == "a", "new PrintingDeviceAttributes() should include a 'info' property.");
-	});	
-	module('Braille Device Type Property');
-	test("should be able to define a Printing Device Property object", function() {
-		expect(3);
-		var braille = new BrailleDeviceAttributes(0,"a");
-		ok(braille  != null, "new BrailleDeviceAttributes() should not be null.");
-		ok(typeof braille.nbCells != 'undefined' && braille.nbCells != null && braille.nbCells == 0, "new BrailleDeviceAttributes() should include a 'nbCells' property.");
-		ok(typeof braille.info != 'undefined' && braille.info != null && braille.info == "a", "new BrailleDeviceAttributes() should include a 'info' property.");
-	});	
-	module('Input Devices Property');
-	test("should be able to define a Input Devices Property object", function() {
-		expect(11);
-		var input = new InputDevicesAttributes('a','b',[],[],[],[],[],[],[],[]);
-		ok(input != null, "new InputDevicesAttributes() should not be null.");
-		ok(typeof input.info != 'undefined' && input.info != null && input.info == "a", "new InputDevicesAttributes() should include a 'info' property.");
-		ok(typeof input.id != 'undefined' && input.id != null && input.id == "b", "new InputDevicesAttributes() should include a 'id' property.");
-		ok(typeof input.pointingDevices != 'undefined' && input.pointingDevices != null, "new InputDevicesAttributes() should include a 'pointingDevices' property.");
-		ok(typeof input.activePointingDevices != 'undefined' && input.activePointingDevices != null, "new InputDevicesAttributes() should include a 'activePointingDevices' property.");
-		ok(typeof input.keyboards != 'undefined' && input.keyboards != null, "new InputDevicesAttributes() should include a 'keyboards' property.");
-		ok(typeof input.activeKeyboards != 'undefined' && input.activeKeyboards != null, "new InputDevicesAttributes() should include a 'activeKeyboards' property.");
-		ok(typeof input.cameras != 'undefined' && input.cameras != null, "new InputDevicesAttributes() should include a 'cameras' property.");
-		ok(typeof input.activeCameras != 'undefined' && input.activeCameras != null, "new InputDevicesAttributes() should include a 'activeCameras' property.");
-		ok(typeof input.microphones != 'undefined' && input.microphones != null, "new InputDevicesAttributes() should include a 'microphones' property.");
-		ok(typeof input.activeMicrophones != 'undefined' && input.activeMicrophones != null, "new InputDevicesAttributes() should include a 'activeMicrophones' property.");
-	});	
-	module('Pointer Property');
-	test("should be able to define a Pointer Property object", function() {
-		expect(4);
-		var pointer = new PointerAttributes(0,true,"a");
-		ok(pointer  != null, "new PointerAttributes() should not be null.");
-		ok(typeof pointer.type != 'undefined' && pointer.type != null && pointer.type == 0, "new PointerAttributes() should include a 'type' property.");
-		ok(typeof pointer.supportsMultiTouch != 'undefined' && pointer.supportsMultiTouch != null && pointer.supportsMultiTouch == true, "new PointerAttributes() should include a 'supportsMultiTouch' property.");
-		ok(typeof pointer.info != 'undefined' && pointer.info != null && pointer.info == "a", "new PointerAttributes() should include a 'info' property.");
-	});	
-	module('Keyboard Property');
-	test("should be able to define a Keyboard Property object", function() {
-		expect(4);
-		var keyboard = new KeyboardAttributes(0,true,"a");
-		ok(keyboard  != null, "new KeyboardAttributes() should not be null.");
-		ok(typeof keyboard.type != 'undefined' && keyboard.type != null && keyboard.type == 0, "new KeyboardAttributes() should include a 'type' property.");
-		ok(typeof keyboard.isHardware != 'undefined' && keyboard.isHardware != null && keyboard.isHardware == true, "new KeyboardAttributes() should include a 'isHardware' property.");
-		ok(typeof keyboard.info != 'undefined' && keyboard.info != null && keyboard.info == "a", "new KeyboardAttributes() should include a 'info' property.");
-	});	
-	module('Camera Property');
-	test("should be able to define a Camera Property object", function() {
-		expect(5);
-		var camera = new CameraAttributes(true,true,0,0.0);
-		ok(camera  != null, "new CameraAttributes() should not be null.");
-		ok(typeof camera.supportsVideo != 'undefined' && camera.supportsVideo != null && camera.supportsVideo == true, "new CameraAttributes() should include a 'supportsVideo' property.");
-		ok(typeof camera.hasFlash != 'undefined' && camera.hasFlash != null && camera.hasFlash == true, "new CameraAttributes() should include a 'hasFlash' property.");
-		ok(typeof camera.sensorPixels != 'undefined' && camera.sensorPixels != null && camera.sensorPixels == 0, "new CameraAttributes() should include a 'sensorPixels' property.");
-		ok(typeof camera.maxZoomFactor != 'undefined' && camera.maxZoomFactor != null && camera.maxZoomFactor == 0.0, "new CameraAttributes() should include a 'maxZoomFactor' property.");
-	});	
-	module('Microphone Property');
-	test("should be able to define a Microphone Property object", function() {
-		expect(7);
-		var mic = new MicrophoneAttributes(0,0,0,"a","b",[]);
-		ok(mic  != null, "new MicrophoneAttributes() should not be null.");
-		ok(typeof mic.type != 'undefined' && mic.type != null && mic.type == 0, "new MicrophoneAttributes() should include a 'type' property.");
-		ok(typeof mic.freqRangeLow != 'undefined' && mic.freqRangeLow != null && mic.freqRangeLow == 0, "new MicrophoneAttributes() should include a 'freqRangeLow' property.");
-		ok(typeof mic.freqRangeHigh != 'undefined' && mic.freqRangeHigh != null && mic.freqRangeHigh == 0, "new MicrophoneAttributes() should include a 'freqRangeHigh' property.");
-		ok(typeof mic.info != 'undefined' && mic.info != null && mic.info == "a", "new MicrophoneAttributes() should include a 'info' property.");
-		ok(typeof mic.name != 'undefined' && mic.name != null && mic.name == "b", "new MicrophoneAttributes() should include a 'name' property.");
-		ok(typeof mic.types != 'undefined' && mic.types != null, "new MicrophoneAttributes() should include a 'types' property.");
-	});	
-};
diff --git a/Res/mobile-spec/tests/telephony.tests.js b/Res/mobile-spec/tests/telephony.tests.js
deleted file mode 100644
index 0089689..0000000
--- a/Res/mobile-spec/tests/telephony.tests.js
+++ /dev/null
@@ -1,12 +0,0 @@
-Tests.prototype.TelephonyTests = function() {	
-	module('Telephony (navigator.telephony)');
-	test("should exist", function() {
-  		expect(1);
-  		ok(navigator.telephony != null, "navigator.telephony should not be null.");
-	});
-	test("should contain a send function", function() {
-		expect(2);
-		ok(typeof navigator.telephony.send != 'undefined' && navigator.telephony.send != null, "navigator.telephony.send should not be null.");
-		ok(typeof navigator.telephony.send == 'function', "navigator.telephony.send should be a function.");
-	});
-};
\ No newline at end of file
